質問
このC#のスニペットを考えてみます:
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ます:
.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
}
私を困惑作品は、次のとおりです。
L_0010: stloc.0
L_0011: br.s L_0013
L_0013: ldloc.0
これは、(とにかく実行されていたであろう)次の行に項目、枝を保存し、再度ロードします。
この理由はありますか?
解決
このだけではないリリースでは、デバッグ中に起こります。私は、その中には、デバッグを支援するために疑います。それはおそらく、あなたがブレークポイントに半ば文をチャックと戻り値を参照することができます。
リリースバージョンに注意してください持ってはるかに簡潔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
}
他のヒント
私の推測では、これはreturn文を実行するための定型コードがあると、コンパイラは最後の行に無条件ジャンプを実行している、とret
を実行する前にレジスタに戻り値をロードします。 JITが良いそれを最適化します、私は、コンパイラは任意の最適化をやって気にしませんだと思います。
所属していません StackOverflow