Bu iki koddan hangisi 'daha iyi'? Yerel değişken mi, sınıf değişkeni mi?


11

Daha fazla oyun yapıyorum ve daha aptalca sorular soruyorum.

Umarım bu çok kısa. Katı bir cisme kuvvet uygulayarak bir Player nesnesini hareket ettiren çok temel bir sınıf yapıyorum, ama rb için bir sınıf referansı yapmalı mıyım, yoksa her kareyi güncelle içindeki bir yerel değişken mi? (Monobehaviour.GameObject birlik üst sınıfında zaten var olduğunu göz önünde bulundurarak).

Ben birçok yerel değişkenler yapmak bir bütün olarak döngü yavaş olup olmadığını merak ediyorum (yerel ben fonksiyonun içinde demek ve sınıfın üstünde değil - umut im doğru terimi kullanarak).

Demek istediğim, bunu yapmayı düşündüğüm iki yol:

public class Player : MonoBehaviour {

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

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

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

veya...

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);
}
}

4
Bu daha çok kod inceleme SE için bir soru gibi görünüyor.
Orphevs

1
Ayrıca float va class özelliği yapabilirsiniz.
Çad

Muhtemelen sonunda Chad olacak, çünkü sınıf içinde iki yöntemle kullanacağım. Çok sayıda kodla şişirmeden yerel vs sınıf değişkenleri hakkında soru sormak gerçekten basit bir koddu. Değişkenleri yerel olarak (ve nerede olduğu gibi 'yolumdan' tutmaktan hoşlanıyorum ama tabii ki her biri için bir sınıf değişkeni yerine bir şeyleri çoğaltmaya başlamadığından emin olmalıyım.
Büyük T Larrity

Kod pasajı 'kod' değildir. 'Hangi kodun daha iyi olduğunu' sormak sizi amatör gibi gösterir.
Miles Rout

1
ben bir amatör öylesine thats benimle iyi teşekkürler Miles
Big T Larrity

Yanıtlar:


25

Genel olarak, başlamak için verileri olabildiğince dar bir şekilde kapsamalı ve ihtiyacınız olduğunu keşfettiğiniz kapsamı genişletmelisiniz. Eğer yollarla Yani olabilir yerel bir değişken yerine bir üyesi yapmak, muhtemelen orada başlamalıdır.

Bunun nedeni, daha dar bir kapsamın koddaki bu veriler hakkında gerekçelendirmeniz gereken yer sayısını azaltması ve dolayısıyla hatalı bir şekilde gerekçelendirebileceğiniz yerlerin sayısını azaltmasıdır (bu da hatalara yol açar).

Aslında yerel değişkenlerin tek başına beyan edilmesi hiçbir zaman pratikte bir performans sorunu olmayacaktır: ucuzdurlar ve modern derleyiciler "ekstraları" bile optimize edebilir.

Bunları başlatmak bir sorun olabilir; sizin durumunuzda rijit vücudunuz her seferinde aranır GetComponent, bu da sıfır olmayan bir maliyete sahiptir. Katı gövde bileşeninin bu belirli oyun nesnesi için değişmeyeceğini biliyorsanız, bir kez arayabilir ve sonucu bir üye değişkeninde saklayabilir ve küçük bir çağrı başına ek yükten kaçınabilirsiniz.

Bu örnekte çağrı başına ek yükün önemli olması pek olası değildir, ancak zaman içinde bunu birçok bileşen için yapmanız gerekebilir. Emin olmak için bir profil oluşturucu uygulamak istersiniz.

Özetlemek gerekirse: genel olarak, işleri olabildiğince yerel hale getirme varsayılanıdır, ancak bu durumda rbbir üye yapmak muhtemelen makul olur, böylece aramayı bir kez gerçekleştirebilir Awakeve her FixedUpdateçağrıda yapmaktan kaçınabilirsiniz .


1
Teşekkürler Josh, rb'nin sadece bir kez başlatılmasının daha iyi olacağını hissettim ve nedenini açıklamak için çok teşekkürler. Herhalde GetComponent'in her seferinde başlatma olarak sayıldığından ya da sadece Monobehaviour'dan 'baktığından' emin olmadığımı bilmek güzel. Ama şimdi süper hızlı yardımcı cevap için çok teşekkürler
Big T Larrity

1
@SuperMegaBroBro GetComponent olduğunu oldukça hızlı - Sabit karşılaştırılabilir hıza sahip arama her türlü yapım baskı olurdu. Sorun olduğunu gösteren performans verileriniz yoksa, "işleri yerel tut" yaklaşımına sadık kalın. Daha sonra istediğiniz zaman optimize edebilirsiniz. Bkz answers.unity.com/questions/185164/... Eğer her önbelleğe eğer - Do o önbelleğe alma ya özgür değildir unutma GetComponentOyununuzda, bu edeceğiz muhtemelen net kayıp. Ölçün. Optimizasyonların buna değdiğini belirleyin. Harika bir oyun yapmaya odaklan :)
Luaan

1
Bu cevaptan (ki oldukça iyi) uzaklaşmanız gereken ana öz: şudur: Akıl yürütmek, test etmek ve hatasız olmasını sağlamak için en kolay kod için gitmek istiyorsanız, yerel değişkeni alın. Ancak, her zaman olduğu gibi, bazen performans nedenleriyle mükemmel kod için fedakarlık yapmamız gerekir , bu nedenle bir sınıf üyesi uygun olabilir (ancak önce profil, sadece erken optimizasyon yapmayın).
Polygnome

Çok teşekkürler çocuklar, özellikle Luaan ben orijinal soruyu yazarken bu 'önbellekleme' sorunu hakkında merak ediyordum (ama gerçekten nasıl kelime bilmiyordum). Kesinlikle mümkün olduğunca 'yerel' yaklaşımı benimseyeceğim. her zamanki gibi tüm büyük yardım için teşekkürler arkadaşlar.
Büyük T Larrity

2

Josh Petrie'nin cevabı çok iyi - işte tamamlayıcı bir bakış açısı.

Oldukça iyi etki alanını anladığınız kodla çalıştığınızda, değişkenleri anlamlı oldukları yere dahil edebilirsiniz.

Örneğin Person, bir waveGoodbyeyöntemle bir sınıfım varsa , sınıfımın daha handönce bir nesnesi olmaması mümkündür ve böylece yerel olarak bildirebilirim waveGoodbye. Şimdi burada bir kişinin eli olduğu açıktır, bu yüzden onu Persondüşünmeden doğal olarak bir üye olarak ilan edebilirsiniz, ancak aynı sorun geçerlidir.

handYerel olarak beyan ederseniz, daha sonra karateChopbir el gerektiren bir yöntem de ekleyebilirsiniz . Bu, değişkenlerin yerel olarak bildirilmesinin sorunlu olabileceği zamandır - çünkü genç geliştiriciler genellikle beyanı kopyalamak / yapıştırmak için geri döner waveGoodbyeve şimdi aynı noktada iki noktada bulunur. Daha handsonra yapılacak değişikliklerin her iki yerde de değiştirilmesi gerekir ve böylece bir karınca böcek tepesi başlar .

Sonuçta,

  1. Beyanınızın yerleştirilmesinden eminseniz, mantıklı olduğu yere ekleyin.

  2. Kendinden emin değilseniz, yerel olarak başlayın ve bir miktar kod yeniden kullanıldığında yeniden düzenleme yaptığınızdan emin olun.

Edit: Oh ve aynı hata yapmayın ben beyanları kapsamı nerede bulmak için çok fazla zaman harcamak var. Verilerinizin yapısını önceden anlamak zordur ve kodunuzu yazarken yapının kendini göstermenin bir yolu vardır.


2
Ayrıca her gibi şeyler doğal olarak, sipariş sahip Personüyesi olmalıdır hand onun ilgiliyse uygulamasında, genellikle diğer geliştiriciler (çoğu kez yardımcı olur size daha iyi kod anlamak için 6 ay sonra). Bu durumda, bir Rigidbodyüyesi olarak bir mantık var gibi görünüyor Playerve ben daha çok söylüyorum, bu daha kötü performans anlamına gelse bile. Video oyunlarında dikkate alakalı bir nokta olduğunu, ama sanırım kodunda net olmak çoğu zaman daha önemlidir,
alseether

1
mükemmel cevaplar teşekkürler çocuklar. Bilmiyorum gibi görünmeye çalışmıyorum, ama tüm bu cevaplar zaten düşündüğüm şeyi tekrar doğruladı, bu yüzden çok mutlu olduğum ve oyunlarımda güzel bir ilerleme kaydettim. Şu anda uygun animasyonlar ve her şeyle bir 3d futbol oyunu yapıyorum, gerçek adımlar atıyorum: D Yakında burada 2 oyunculu ve cüretkâr diyorum ki çevrimiçi mulitplayer diyorum: D eğlenin çocuklar ve tekrar teşekkürler!
Büyük T Larrity
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.