Welcher dieser beiden Codes ist "besser"? Eine lokale Variable oder eine Klassenvariable erstellen?

11

Ich mache mehr Spiele und stelle mehr dumme Fragen.

Hoffentlich ist dieser sehr kurz. Ich mache eine sehr einfache Klasse, die nur ein Player-Objekt bewegt, indem sie Kraft auf einen starren Körper ausübt, aber ich habe mich gefragt, ob ich eine Klassenreferenz auf das rb oder nur eine lokale Variable in Update jedes Frames erstellen soll. (Beachten Sie, dass es bereits in der übergeordneten Klasse Monobehaviour.GameObject Unity vorhanden ist.)

Ich frage mich, ob das Ausführen vieler lokaler Variablen die Schleife als Ganzes verlangsamen würde (mit lokal meine ich innerhalb der Funktion selbst und nicht an der Spitze der Klasse - ich hoffe, ich verwende den richtigen Begriff).

Hier ist, was ich meine, die zwei Arten, wie ich es mir vorgestellt habe:

public class Player : MonoBehaviour {

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

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

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

oder...

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
quelle
4
Dies scheint eher eine Frage für die Codeüberprüfung SE zu sein.
Orphevs
1
Sie können auch float va class property machen.
Chad
Ich werde wahrscheinlich am Ende tatsächlich Tschad, weil ich es in zwei Methoden innerhalb der Klasse verwenden werde. Es war wirklich nur einfacher Code, um die Frage nach lokalen und Klassenvariablen zu vermitteln, ohne sie mit viel Code aufzublähen. Ich mag es wirklich, die Variablen lokal zu halten (und "aus dem Weg", wie es ist!), Aber natürlich muss ich sicherstellen, dass ich nicht anfange, Dinge zu duplizieren, anstatt für jede eine Klassenvariable zu haben.
Big T Larrity
Ein Codeausschnitt ist kein Code. Wenn Sie nach dem Code fragen, der besser ist, sehen Sie aus wie ein Amateur.
Miles Rout
1
Ich bin ein Amateur, also ist das in Ordnung mit mir, danke Miles
Big T Larrity

Antworten:

25

Im Allgemeinen habe ich festgestellt, dass Sie den Umfang der Daten zunächst so eng wie möglich gestalten und erweitern sollten, wenn Sie feststellen, dass Sie dies benötigen. Das heißt , wenn Sie kann es sich um eine lokale Variable statt Mitglied machen, sollten Sie wahrscheinlich dort beginnen.

Dies liegt daran, dass ein engerer Bereich die Anzahl der Stellen im Code verringert, an denen Sie über diese Daten argumentieren müssen, und somit die Anzahl der Stellen verringert, an denen Sie falsch argumentieren können (was zu Fehlern führt).

Das Deklarieren lokaler Variablen allein wird praktisch nie ein Leistungsproblem sein: Sie sind billig, und moderne Compiler können sogar "Extras" optimieren.

Das Initialisieren kann ein Problem sein. In Ihrem Fall wird Ihr starrer Körper jedes Mal über nachgeschlagen GetComponent, was einige Kosten ungleich Null verursacht. Wenn Sie wissen, dass sich die Starrkörperkomponente für dieses bestimmte Spielobjekt nicht ändert , können Sie sie einmal nachschlagen und das Ergebnis in einer Mitgliedsvariablen speichern, um einen kleinen Aufwand pro Anruf zu vermeiden.

Es ist unwahrscheinlich, dass der Overhead pro Anruf in diesem einen Fall erheblich sein wird, aber im Laufe der Zeit kann sich dies für viele Komponenten summieren. Sie möchten sicher einen Profiler anwenden.

Zusammenfassend rblässt sich Awakesagen, dass es im Allgemeinen standardmäßig darum geht, die Dinge so lokal wie möglich zu gestalten. In diesem Fall ist es jedoch wahrscheinlich sinnvoll, ein Mitglied zu erstellen, damit Sie die Suche einmal durchführen und vermeiden müssen, dass Sie sie bei jedem FixedUpdateAnruf ausführen müssen .


quelle
1
danke Josh, ich hatte das Gefühl, es wäre besser, wenn der rb nur einmal initialisiert würde, und vielen Dank, dass du klar erklärt hast, warum. Es ist schön zu wissen, dass ich nicht 100% sicher war, dass die GetComponent jedes Mal als Initialisierung oder einfach als "Nachschlagen" vom Monobehaviour gezählt wurde. Aber jetzt bekomme ich es so vielen Dank für die superschnelle hilfreiche Antwort
Big T Larrity
1
@SuperMegaBroBro GetComponent ist ziemlich schnell - es würde Ihnen schwer fallen, eine Suche mit vergleichbarer Geschwindigkeit durchzuführen . Wenn Sie keine Leistungsdaten haben, die darauf hindeuten, dass es sich um ein Problem handelt, halten Sie sich an den Ansatz "Dinge lokal halten". Sie können es später jederzeit optimieren. Siehe answers.unity.com/questions/185164/… Vergessen Sie nicht, dass das Caching auch nicht kostenlos ist - wenn Sie jedes einzelne GetComponentin Ihrem Spiel zwischenspeichern, ist dies wahrscheinlich ein Nettoverlust. Messen. Identifizieren Sie, wo sich Optimierungen lohnen. Konzentriere dich darauf, ein großartiges Spiel zu machen :)
Luaan
1
Das Wichtigste, was Sie aus dieser Antwort herausnehmen sollten (was ziemlich gut ist), ist: Wenn Sie sich für Code entscheiden möchten, der am einfachsten zu überlegen, zu testen und sicherzustellen ist, dass er fehlerfrei ist, nehmen Sie die lokale Variable. Aber wie immer müssen wir manchmal aus Leistungsgründen Opfer bringen, um den Code zu perfektionieren , sodass ein Klassenmitglied möglicherweise angemessen ist (aber Profil zuerst, nicht einfach vorzeitige Optimierung durchführen).
Polygnome
Vielen Dank Jungs, besonders Luaan, als ich mich über dieses 'Caching'-Problem wunderte, während ich die ursprüngliche Frage schrieb (aber ich wusste nicht wirklich, wie ich das ausdrücken sollte). Ich werde mit Sicherheit so weit wie möglich den "lokalen" Ansatz verfolgen. Vielen Dank für die große Hilfe wie immer Jungs.
Big T Larrity
2

Die Antwort von Josh Petrie ist sehr gut - hier ist eine ergänzende Perspektive.

Wenn Sie mit Code arbeiten, dessen Domäne Sie ziemlich gut verstehen, können Sie Variablen dort platzieren, wo sie sinnvoll sind.

Wenn ich beispielsweise eine PersonKlasse mit einer waveGoodbyeMethode habe, ist es möglich, dass meine Klasse zuvor kein handObjekt hatte und ich es daher lokal deklarieren kann waveGoodbye. Hier ist es offensichtlich, dass eine Person eine Hand hat, so dass Sie sie natürlich als Mitglied deklarieren können, Personohne darüber nachzudenken, aber das gleiche Problem gilt.

Wenn Sie handlokal deklarieren, können Sie später eine karateChopMethode hinzufügen , für die ebenfalls eine Hand erforderlich ist. In diesem Fall kann das lokale Deklarieren von Variablen problematisch werden, da Junior-Entwickler häufig auf das Kopieren / Einfügen der Deklaration zurückgreifen waveGoodbyeund jetzt dasselbe Konzept an zwei Stellen installiert ist. Alle Änderungen handmüssen dann an beiden Stellen geändert werden und beginnen somit einen Ameisenbug- Hügel.

Alles in allem also

  1. Wenn Sie von der Platzierung Ihrer Erklärung überzeugt sind, legen Sie sie dort fest, wo es sinnvoll ist.

  2. Wenn Sie sich nicht sicher sind, starten Sie local und stellen Sie sicher, dass Sie den Refactor verwenden, wenn Sie einen Hauch von Code-Wiederverwendung erhalten.

Bearbeiten: Oh und machen Sie nicht den gleichen Fehler, den ich habe, wenn Sie zu viel Zeit damit verbringen, herauszufinden, wo Sie Ihre Erklärungen einordnen können. Es ist schwierig, die Struktur Ihrer Daten im Voraus zu verstehen, und während Sie Ihren Code schreiben, kann sich die Struktur offenbaren.

aaaaaa
quelle
2
Auch Dinge natürlich bestellt hat, wie jeder Personsollte das Element haben , hand wenn ihre maßgebenden in der Anwendung, hilft oft andere Entwickler (meistens Sie 6 Monate später) , um besser den Code zu verstehen. In diesem Fall scheint es logisch, ein RigidbodyMitglied von Ihnen zu haben, Playerund ich sage mehr, auch wenn dies eine schlechtere Leistung impliziert. In Videospielen ist dies ein relevanter Punkt, den ich berücksichtigen muss, aber ich denke, dass es im Code oft wichtiger ist, klar zu sein
am
1
ausgezeichnete Antworten danke Jungs. Ich versuche nicht, wie ein Besserwisser zu klingen, aber all diese Antworten haben nur bestätigt, was ich bereits gedacht habe. Ausnahmsweise bin ich sehr glücklich und mache einige schöne Fortschritte in meinen Spielen. Im Moment mache ich ein 3D-Fußballspiel mit richtigen Animationen und allem und mache echte Fortschritte: D Bald werde ich hier sein und Hilfe brauchen, um es für 2 Spieler zu machen, und ich wage es zu sagen, Online-Mulitplayer: D hab Spaß, Leute, und nochmals vielen Dank!
Big T Larrity