Die folgende C# Funktion:Was ist der Zweck der zusätzlichen LDNULL und Tail. in F # Implementierung vs C#?
T ResultOfFunc<T>(Func<T> f)
{
return f();
}
kompiliert unsurprisingly dazu:
IL_0000: ldarg.1
IL_0001: callvirt 05 00 00 0A
IL_0006: ret
Aber die äquivalente # Funktion F:
let resultOfFunc func = func()
dazu kompiliert:
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldnull
IL_0003: tail.
IL_0005: callvirt 04 00 00 0A
IL_000A: ret
(Beide sind im Freigabemodus). Es gibt ein extra Nop am Anfang, auf das ich nicht sonderlich neugierig bin, aber das Interessante ist die extra Anleitung ldnull
und tail.
.
Meine Vermutung (wahrscheinlich falsch) ist, dass ldnull
, falls notwendig, ist die Funktion void
ist so still es gibt etwas (unit
), aber das erklärt nicht, was der Zweck der tail.
Anweisung ist. Und was passiert, wenn die Funktion etwas auf den Stapel drückt, ist es nicht mit einer zusätzlichen Null verbunden, die nicht geknallt wird?
Ich vermute, dass in diesem Fall die Funktion zu einem Tail-Aufruf konvertiert wurde - die neue Funktion verwendet den Stack-Bereich des alten –
Beachten Sie, dass dies wahrscheinlich eine Performance-Pessimierung verursacht, siehe diese Frage: [Leistung Penalty, wenn Generic.List .Add ist die letzte Anweisung in einer Funktion und die Optimierung der Endlosschleife ist aktiviert] (http://stackoverflow.com/q/28649422/636019) –
ildjarn