In C # haben Sie möglicherweise den folgenden Code:
%Vor%Sobald Sie DoSomething eingeben, richtet die CLR Platz für int x ein. Warum wartet es nicht, bis es die Zeile mit int x = 5 erreicht? Vor allem, obwohl x gebunden ist, lässt es Sie nicht wirklich verwenden, bis diese Zeile überhaupt erreicht wird?
Sobald Sie
DoSomething
eingeben, richtet die CLR den Platz fürint x
ein. Warum wartet es nicht, bis es die Zeile mitint x = 5
erreicht?
Die Frage ist nicht zu beantworten, weil die ganze Frage auf einer falschen Prämisse beruht. Der Speicherplatz für die lokale Variable kann sein:
Der C # -Compiler und der JIT-Compiler stellen auf jeden Fall sicher, dass der lokale Speicher auf eine Weise zugewiesen wird, die korrekt ist, und versuchen, sicherzustellen, dass er effizient ist. Wie sie dies tun, hängt von der genauen Situation ab. Es könnte effizienter sein, den Speicherplatz im Voraus zuzuweisen, und es ist möglicherweise effizienter, ihn nur so lange zuzuweisen, wie die Variable verwendet wird. Der Jitter ist bei der Wahl der Lebensdauer einer lokalen Variablen mit einer breiten Breite zulässig. Lokale Variablen dürfen länger und kürzer leben als ihre Gültigkeitsbereiche, wenn der Jitter dies ohne Verletzung der Programmkorrektheit tun könnte.
Da die Prämisse der Frage falsch ist, gibt es keine Antwort auf die Frage. Stellen Sie eine bessere Frage.
Wie Sie vielleicht wissen, gibt es mehrere Schritte vom C # -Code zum nativen Code, die sind:
C # hat keine Kontrolle über die Zeit, wenn Speicher zugewiesen wird, was Sie binding nennen, dies liegt ganz bei JIT. Wenn wir dies aus dem Weg räumen, sehen wir, was in C # ist. Der von C # erzeugte Byte-Code muss dem Standard CLR ECMA entsprechen. Wenn wir zu Abschnitt 12.1.6.1 von Partition 1 gehen, werden wir sehen, dass der Standard definiert, dass die Heimatvariable der lokalen Variable im Methodenkopf ist. Da Methodensignaturen in der Regel am Anfang einer Methode in einer Auflistung angezeigt werden, erhalten Sie eine (falsche) Vorstellung, dass sie im Voraus gebunden sind , was tatsächlich der Fall sein kann oder auch nicht .
Wenn Sie jedoch den kompilierten nativen Code betrachten, kann das Ergebnis von Plattform zu Plattform variieren. Die Zuweisung von Speicherplatz auf dem CPU-Stack für eine lokale Variable erfolgt in der Vergangenheit durch einen einzelnen CPU-Befehl zum Ändern des Stack-Pointers. Wenn Sie es Variable für Variable tun wollen, dann haben Sie viele Anweisungen, einen pro Variable, was weniger effizient ist. Aus diesem Grund werden Sie zumindest auf x86 sehen, dass der Speicherplatz auf dem CPU-Stack im Voraus zugewiesen wird.
Was sollte der Compiler tun, wenn er etwas Ähnliches findet wie:
%Vor%Außerdem denke ich wirklich, dass die Kosten für die Einrichtung von Lokalen kein Faktor sind. Wenn es dann zu tun ist, haben Sie wahrscheinlich viel zu viele Einheimische in einer einzigen Methode und Sie sind besser dran Refactoring Ihres Codes.
Ihre Frage scheint auf einigen Annahmen zu beruhen:
Das mag für Ihren Code stimmen, aber möglicherweise nicht für den Großteil des Codes da draußen.
Die Annahmen scheinen auch das Vorhandensein von darunter liegenden Schichten des Prozesses zu ignorieren, die dies bis zum Maschinencode kompilieren / interpretieren.
Kurz gesagt, der Code, den Sie in C # schreiben, ist eine Abstraktion, die auf IL beruht, die eine andere Abstraktion ist, die auf der CLR beruht, die eine andere Abstraktion ist usw.
Für das, was es wert ist, habe ich ernsthafte Zweifel daran, dass diese Entscheidung jemals einen erheblichen Einfluss auf die Leistung Ihrer Anwendung gehabt hat ... aber vielleicht ist das ähnlich wie bei Eric Lippert ( Ссылка ) kann eine ausführlichere Analyse teilen.