Ich denke, es gibt einige Verwirrung über die Art, wie Compiler mit Variablen umgehen. Aus einer hochrangigen Art menschlicher Sichtweise ist es natürlich, daran zu denken, eine Variable zu definieren und zu zerstören, um damit irgendeine Art von "Kosten" zu verbinden.
Das ist jedoch nicht unbedingt der optimierende Compiler. Die Variablen, die Sie in einer höheren Sprache erstellen, ähneln eher temporären "Handles" im Speicher. Der Compiler betrachtet diese Variablen und übersetzt sie dann in eine Zwischendarstellung (etwas, das näher an der Maschine liegt) und ermittelt, wo alles gespeichert werden soll, hauptsächlich mit dem Ziel der Zuweisung von Registern (die unmittelbarste Form von Speicher für die CPU). Dann übersetzt es das IR in Maschinencode, wo die Idee einer "Variablen" gar nicht existiert, nur Orte zum Speichern von Daten (Register, Cache, Dram, Disk).
Dieser Prozess beinhaltet die Wiederverwendung derselben Register für mehrere Variablen, vorausgesetzt, dass sie sich nicht gegenseitig stören (vorausgesetzt, sie werden nicht gleichzeitig benötigt: nicht gleichzeitig "live").
Anders ausgedrückt, mit Code wie:
local a = <some expression>
Die resultierende Anordnung so etwas wie sein könnte:
load gp_register, <result from expression>
... oder es kann bereits von einem Ausdruck in einem Register das Ergebnis , und die Variable verschwindet schließlich vollständig (nur mit dem gleichen Register dafür).
... was bedeutet, dass es keine "Kosten" für die Existenz der Variablen gibt. Es übersetzt sich einfach direkt in ein Register, das immer verfügbar ist. Es gibt keine "Kosten" für "Erstellen eines Registers", da Register immer vorhanden sind.
Wenn Sie beginnen, Variablen in einem breiteren (weniger lokalen) Bereich zu erstellen, im Gegensatz zu dem, was Sie denken, können Sie verlangsamen den Code. Wenn Sie dies oberflächlich tun, kämpfen Sie gegen die Registerzuordnung des Compilers und machen es dem Compiler schwerer, herauszufinden, welche Register für was zuzuteilen sind. In diesem Fall könnte der Compiler mehr Variablen in den Stapel einbringen, was weniger effizient ist und tatsächlich Kosten verursacht. Ein intelligenter Compiler kann immer noch gleich effizienten Code ausgeben, aber Sie könnten die Dinge tatsächlich langsamer machen . Dem Compiler hier zu helfen, bedeutet oft mehr lokale Variablen, die in kleineren Bereichen verwendet werden, in denen Sie die besten Chancen auf Effizienz haben.
Im Assembler-Code ist die Wiederverwendung der gleichen Register wann immer möglich, effizient, um das Verschütten von Stapeln zu vermeiden. In Hochsprachen mit Variablen ist das Gegenteil der Fall. Reduzieren Sie den Umfang der Variablen hilft der Compiler herauszufinden, welche Register es wiederverwenden kann, da die Verwendung eines lokalen Bereichs für Variablen hilft, den Compiler zu informieren, welche Variablen nicht gleichzeitig aktiv sind.
Jetzt gibt es Ausnahmen, wenn Sie beginnen, benutzerdefinierte Konstruktor- und Destruktorlogik in Sprachen wie C++ zu verwenden, wo die Wiederverwendung eines Objekts redundante Konstruktion und die Zerstörung eines Objekts verhindern kann, das wiederverwendet werden kann. Aber das gilt nicht in einer Sprache wie Lua, wo alle Variablen im Grunde einfach alte Daten sind (oder in von Müll gesammelten Daten oder Benutzerdaten verarbeitet werden).
Der einzige Fall, in dem Sie möglicherweise eine Verbesserung mit weniger lokalen Variablen sehen, ist, wenn dies die Arbeit für den Garbage Collector irgendwie reduziert. Aber das wird nicht der Fall sein, wenn Sie einfach auf die gleiche Variable zuweisen. Dazu müssten Sie ganze Tabellen oder Benutzerdaten (ohne Neuzuweisung) wiederverwenden. Mit anderen Worten, die Verwendung der gleichen Felder einer Tabelle, ohne dass ein ganz neues neu erstellt werden muss, kann in manchen Fällen hilfreich sein, aber es ist sehr unwahrscheinlich, dass die zur Referenzierung der Tabelle verwendete Variable die Performance beeinträchtigt.
"Erstellen einer lokalen Variablen" ist etwas, was Sie tun, wenn Sie Quellcode schreiben. Was zur Laufzeit passiert, ist, wie ich annehme, Ihnen so unbekannt wie mir. (Okay, ich habe mit 'Luac -l' gespielt und etwas über den VM-Befehlssatz gelesen.) –