Manakah dari dua kode ini yang 'lebih baik'? Membuat variabel lokal atau variabel kelas?

11

Saya membuat lebih banyak game dan mengajukan lebih banyak pertanyaan bodoh.

Semoga yang ini sangat singkat. Saya membuat kelas yang sangat mendasar yang hanya memindahkan objek Player dengan memberikan kekuatan pada benda tegar, tapi itu membuat saya bertanya-tanya, haruskah saya membuat referensi kelas ke rb atau hanya variabel lokal di dalam Perbarui setiap frame? (mengingat itu sudah ada di kelas induk kesatuan Monobehaviour.GameObject).

Saya bertanya-tanya apakah melakukan banyak variabel lokal akan memperlambat loop secara keseluruhan (oleh lokal saya maksud di dalam fungsi itu sendiri dan bukan di bagian atas kelas - harap saya menggunakan istilah yang benar).

Inilah yang saya maksud, dua cara yang saya pikirkan untuk melakukannya:

public class Player : MonoBehaviour {

private void FixedUpdate()
{
    Rigidbody rb = GetComponent<Rigidbody>();

    float v = Input.GetAxis("Vertical");

    rb.AddForce(v * rb.transform.forward * Const.walkForce);
}
}

atau...

public class Player : MonoBehaviour {
Rigidbody rb;

private void Awake()
{
    rb = GetComponent<Rigidbody>();
}

private void FixedUpdate()
{
    float v = Input.GetAxis("Vertical");

    rb.AddForce(v * rb.transform.forward * Const.walkForce);
}
}
Big T Larrity
sumber
4
Ini sepertinya lebih seperti pertanyaan untuk tinjauan kode SE.
Orphev
1
Anda juga bisa membuat properti kelas float va.
Chad
Saya mungkin pada akhirnya akan benar-benar Chad, karena saya akan menggunakannya dalam dua metode di dalam kelas. Itu benar-benar hanya kode sederhana untuk mendapatkan pertanyaan tentang variabel lokal vs kelas tanpa membengkaknya dengan banyak kode. Saya sangat suka menjaga variabel lokal (dan 'keluar dari jalan' seperti itu di mana!) Tapi tentu saja saya harus memastikan saya tidak mulai menduplikasi hal-hal daripada memiliki satu variabel kelas untuk masing-masing.
Big T Larrity
Cuplikan kode bukan 'kode'. Bertanya tentang 'kode mana yang lebih baik' membuat Anda terlihat seperti seorang amatir.
Rute Mil
1
saya seorang amatir jadi saya baik-baik saja terima kasih Miles
Big T Larrity

Jawaban:

25

Secara umum, saya telah menemukan bahwa Anda harus melakukan scope data sesempit mungkin untuk memulai dan memperluas cakupan sesuai dengan kebutuhan Anda. Itu berarti jika Anda dapat menjadikannya variabel lokal dan bukan anggota, Anda mungkin harus mulai dari sana.

Ini karena ruang lingkup yang lebih sempit mengurangi jumlah tempat dalam kode di mana Anda harus memberi alasan tentang data itu, dan dengan demikian mengurangi jumlah tempat yang dapat Anda alasankan dengan salah (yang mengarah ke bug).

Sebenarnya mendeklarasikan variabel lokal saja tidak pernah praktis menjadi masalah kinerja: mereka murah, dan kompiler modern bahkan dapat mengoptimalkan "ekstra".

Inisialisasi mereka mungkin menjadi perhatian; dalam kasus Anda tubuh kaku Anda dilihat setiap kali melalui GetComponent, yang memiliki beberapa biaya tidak nol. Jika Anda tahu bahwa komponen tubuh yang kaku tidak akan berubah untuk objek game khusus ini, Anda dapat mencarinya sekali dan menyimpan hasilnya dalam variabel anggota dan menghindari sedikit overhead per panggilan.

Tidak mungkin overhead per panggilan akan menjadi signifikan dalam hal ini, tetapi seiring waktu melakukan hal ini untuk banyak komponen dapat bertambah. Anda ingin menerapkan profiler untuk memastikan.

Jadi, untuk meringkas: secara umum, default untuk membuat hal-hal lokal sebagai mungkin, tetapi dalam hal ini mungkin masuk akal untuk membuat rbanggota sehingga Anda dapat melakukan pencarian sekali dalam Awakedan menghindari harus melakukannya setiap FixedUpdatepanggilan.


sumber
1
terima kasih Josh, saya merasa akan lebih baik jika rb diinisialisasi sekali saja, dan terima kasih banyak telah menjelaskan mengapa. Sangat menyenangkan mengetahui dengan pasti, Anda tahu saya tidak 100% yakin bahwa GetComponent dihitung sebagai inisialisasi setiap kali, atau cukup 'mencarinya' dari Monobehaviour. Tapi sekarang saya terima kasih banyak untuk jawaban cepat yang sangat membantu
Big T Larrity
1
@SuperMegaBroBro GetComponent adalah cukup cepat - Anda akan sulit ditekan membuat segala jenis lookup yang memiliki kecepatan yang sebanding. Kecuali jika Anda memiliki data kinerja yang menunjukkan itu masalah, tetaplah dengan pendekatan "simpan segala sesuatu yang lokal". Anda selalu dapat mengoptimalkannya nanti. Lihat answer.unity.com/questions/185164/... Jangan lupa bahwa cache juga tidak gratis - jika Anda melakukan cache setiap satu GetComponentdi game Anda, itu mungkin akan menjadi kerugian bersih. Mengukur. Identifikasi di mana optimalisasi sepadan. Fokus untuk membuat game yang luar biasa :)
Luaan
1
Inti utama yang harus Anda ambil dari jawaban ini (yang cukup bagus) adalah: Jika Anda ingin mencari kode yang paling mudah untuk dipertimbangkan, untuk menguji dan memastikan bahwa itu bebas bug, ambil variabel lokal. Tetapi, seperti biasa, terkadang kita perlu berkorban untuk menyempurnakan kode karena alasan kinerja, jadi anggota kelas mungkin cocok (tetapi profil terlebih dahulu, jangan hanya melakukan optimasi prematur).
Polygnome
terima kasih banyak teman-teman, terutama Luaan karena saya bertanya-tanya tentang masalah 'caching' sementara saya menulis pertanyaan asli (tapi saya tidak benar-benar tahu bagaimana mengatakannya). Saya pasti akan mengambil pendekatan 'lokal' sebanyak mungkin. terima kasih untuk semua bantuan besar seperti teman-teman biasa.
Big T Larrity
2

Jawaban Josh Petrie sangat bagus - inilah perspektif yang saling melengkapi.

Ketika Anda bekerja dengan kode yang Anda mengerti domain dengan cukup baik, Anda bisa menentukan variabel di mana mereka masuk akal.

Sebagai contoh jika saya memiliki Personkelas dengan waveGoodbyemetode, mungkin saja kelas saya tidak memiliki handobjek sebelumnya sehingga saya dapat mendeklarasikannya secara lokal di waveGoodbye. Sekarang di sini sudah jelas seseorang memiliki tangan sehingga Anda mungkin secara alami menyatakannya sebagai anggota Persontanpa memikirkannya, tetapi masalah yang sama berlaku.

Jika Anda menyatakan handlokal kemudian Anda bisa menambahkan sebuah karateChopmetode yang juga membutuhkan tangan. Inilah saat mendeklarasikan variabel secara lokal dapat menjadi masalah - karena pengembang junior sering kembali menyalin / menempel pernyataan dari waveGoodbyedan sekarang Anda memiliki konsep yang sama yang terletak di dua tempat. Setiap perubahan untuk handkemudian perlu dimodifikasi di kedua tempat dan dengan demikian memulai bukit semut bug.

Jadi semuanya,

  1. Jika Anda yakin dengan penempatan deklarasi Anda, ruang lingkup ke tempat itu masuk akal.

  2. Jika Anda tidak percaya diri, mulailah secara lokal dan pastikan untuk melakukan refactor ketika Anda mendapatkan sedikit kode yang digunakan kembali.

Sunting: Oh dan jangan membuat kesalahan yang sama yang saya miliki dengan menghabiskan terlalu banyak waktu mencari tahu di mana ruang lingkup deklarasi Anda. Sulit untuk memahami struktur data Anda di muka, dan ketika Anda menulis kode Anda, struktur memiliki cara untuk mengungkapkannya sendiri.

aaaaaa
sumber
2
Juga memiliki hal-hal yang dipesan secara alami, seperti setiap anggota Personharus memiliki hand jika relevan dalam aplikasi, sering membantu pengembang lain (paling sering Anda 6 bulan kemudian) untuk lebih memahami kode. Dalam hal ini, tampaknya masuk akal untuk memiliki anggota RigidbodyAnda Playerdan, saya katakan lebih banyak, bahkan jika itu menyiratkan kinerja yang lebih buruk. Dalam video-game yang merupakan titik yang relevan untuk dipertimbangkan, tetapi saya pikir dalam kode , untuk menjadi jelas seringkali lebih penting
alseether
1
jawaban yang sangat bagus terima kasih kawan Saya tidak berusaha terdengar seperti orang yang tahu segalanya, tetapi tbh semua jawaban ini baru saja menegaskan kembali apa yang saya pikirkan, jadi untuk sekali ini saya sangat senang dan membuat beberapa kemajuan yang bagus dalam permainan saya. Saat ini saya sedang membuat permainan sepak bola 3d dengan animasi yang tepat dan segalanya, membuat langkah nyata: D segera saya akan berada di sini membutuhkan bantuan tentang cara menjadikannya 2 pemain dan berani saya katakan mulitplayer online: D bersenang-senang guys dan terima kasih lagi!
Big T Larrity