estoy jugando con F # en beta2 VS2010, y como yo soy nuevo en F #, que acaba de recoger uno de los ejemplos más comunes y siguió adelante e implementó una función factorial como:NOP en la liberación de la acumulación de F # Código
let rec factorial n =
if n <= 1 then 1 else n * factorial (n - 1);;
Si construyo esto y miro el código generado en el reflector, consigo el correspondiente código C#:
public static int Factorial(int n) {
if (n <= 1)
return 1;
return n * Factorial(n - 1);
}
Así que si puedo compilar C# representación del reflector del # código F, I sería de esperar para obtener idéntica IL.
Sin embargo, si compilo estos dos fragmentos en modo de lanzamiento y comparo el IL generado, son diferentes (son funcionalmente idénticos, pero aún difieren un poco).
El C# aplicación compila a:
.method public hidebysig static int32 Factorial(int32 n) cil managed
{
.maxstack 8
L_0000: ldarg.0
L_0001: ldc.i4.1
L_0002: bgt.s L_0006
L_0004: ldc.i4.1
L_0005: ret
L_0006: ldarg.0
L_0007: ldarg.0
L_0008: ldc.i4.1
L_0009: sub
L_000a: call int32 TestApp.Program::Factorial(int32)
L_000f: mul
L_0010: ret
}
El F # aplicación compila a:
.method public static int32 factorial(int32 n) cil managed
{
.maxstack 5 <=== Different maxstack
L_0000: nop <=== nop instruction?
L_0001: ldarg.0
L_0002: ldc.i4.1
L_0003: bgt.s L_0007
L_0005: ldc.i4.1
L_0006: ret
L_0007: ldarg.0
L_0008: ldarg.0
L_0009: ldc.i4.1
L_000a: sub
L_000b: call int32 FSharpModule::factorial(int32)
L_0010: mul
L_0011: ret
}
El código generado es idéntico a excepción de diferente maxstack y la instrucción NOP adicional en el método F #.
Esto probablemente no sea significativo, pero tengo curiosidad de por qué el compilador F # insertaría NOP en una compilación de lanzamiento.
¿Alguien puede explicar por qué?
(Estoy perfectamente enterado de que el compilador F # no ha pasado por el mismo nivel de pruebas del mundo real que el compilador C#, pero esto es tan obvio que la imagen podría haberse capturado).
EDIT: El comando de compilación es como sigue
C:\Program Files\Microsoft F#\v4.0\fsc.exe -o:obj\Release\FSharpLib.dll
--debug:pdbonly --noframework --define:TRACE --optimize+
--target:library --warn:3 --warnaserror:76 --vserrors --utf8output --fullpaths
--flaterrors "C:\Temp\.NETFramework,Version=v4.0.AssemblyAttributes.fs" Module1.fs
(ensamblados de referencia eliminan por razones de brevedad).
Bueno, utilizo el perfil de compilación predeterminado "versión" en VS2010, así que supongo que en realidad estoy construyendo en modo de lanzamiento. La ventana de salida dice "Build started: Project: FSharpLib, Configuration: Release Any CPU". Si cambio a "depurar" obtengo un MSIL completamente diferente como se esperaba. –
Estoy probando usando F # 1.9.7.8 y la línea de comando. Si no paso/depuro, no recibo un nop. –
Actualicé la pregunta con la línea de comando para la compilación e intenté compilar usando fsc.exe directamente. Mismo resultado. De acuerdo con la ventana de salida, VS2010b2 no incluye el compilador más reciente ya que informa un número de versión de F # Versión 1.9.7.4. ¿Podría ser esa la diferencia? –