Frage
Betrachten Sie diesen C # Snippet:
static string input = null;
static string output = null;
static void Main(string[] args)
{
input = "input";
output = CallMe(input);
}
public static string CallMe(string input)
{
output = "output";
return output;
}
Dissassembling Reflector zeigt mit:
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
.maxstack 8
L_0000: nop
L_0001: ldstr "input"
L_0006: stsfld string Reflector_Test.Program::input
L_000b: ldsfld string Reflector_Test.Program::input
L_0010: call string Reflector_Test.Program::CallMe(string)
L_0015: stsfld string Reflector_Test.Program::output
L_001a: ret
}
.method public hidebysig static string CallMe(string input) cil managed
{
.maxstack 1
.locals init (
[0] string CS$1$0000)
L_0000: nop
L_0001: ldstr "output"
L_0006: stsfld string Reflector_Test.Program::output
L_000b: ldsfld string Reflector_Test.Program::output
L_0010: stloc.0
L_0011: br.s L_0013
L_0013: ldloc.0
L_0014: ret
}
Das Stück, das mir ein Rätsel ist:
L_0010: stloc.0
L_0011: br.s L_0013
L_0013: ldloc.0
Es speichert das Element, verzweigt in die nächste Zeile (die ohnehin durchgeführt worden wäre) und dann lädt er wieder.
Gibt es einen Grund dafür?
Lösung
Dies geschieht nur in Debug, nicht in Release. Ich vermute, dass sein bei der Fehlersuche zu unterstützen. Es vielleicht können Sie Stützpunkte Mitte Aussage und sehen Sie den Rückgabewert einzuspannen.
Beachten Sie die Release-Version hat viele prägnant IL:
.method private hidebysig static void Main(string[] args) cil managed
{
.maxstack 8
L_0000: ldstr "input"
L_0005: stsfld string Reflector_Test.Program::input
L_000a: ldsfld string Reflector_Test.Program::input
L_000f: call string Reflector_Test.Program::CallMe(string)
L_0014: stsfld string Reflector_Test.Program::output
L_0019: ret
}
.method public hidebysig static string CallMe(string input) cil managed
{
.maxstack 8
L_0000: ldstr "output"
L_0005: stsfld string Reflector_Test.Program::output
L_000a: ldsfld string Reflector_Test.Program::output
L_000f: ret
}
Andere Tipps
Meine Vermutung ist, dass diese Standardcode ist eine return-Anweisung zur Ausführung der Compiler einen unbedingten Sprung in die letzte Zeile ausführt, und lädt den Rückgabewert in ein Register vor dem ret
ausführt. Der JIT wird es besser optimieren, ich denke, der Compiler stört keine Optimierungen zu tun.