sto giocando con F # in VS2010 beta2, e dato che io sono nuovo di F #, ho appena preso uno degli esempi più comuni ed è andato avanti e ha implementato una funzione fattoriale come:NOP in build di rilascio di codice F #
let rec factorial n =
if n <= 1 then 1 else n * factorial (n - 1);;
Se costruisco questo e guardare il codice generato in Reflector, ottengo il codice C# corrispondente:
public static int Factorial(int n) {
if (n <= 1)
return 1;
return n * Factorial(n - 1);
}
Quindi, se compilo rappresentazione C# del riflettore del codice F #, mi sarei aspettato di ottenere identici iL.
Tuttavia, se compilo entrambi questi frammenti nella modalità di rilascio e confrontare l'IL generato, sono diversi (sono funzionalmente identici, ma differisce ancora un po ').
Il C# attuazione 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
}
La # attuazione F 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
}
Il codice generato è identico salvo diversa maxstack e l'istruzione NOP supplementare nel metodo F #.
Questo probabilmente non è significativo, ma sono curioso di sapere perché il compilatore F # sarebbe inserire NOP in una build di rilascio.
Qualcuno può spiegare perché?
(Sono perfettamente consapevole che il compilatore F # non ha superato lo stesso livello di test del mondo reale del compilatore C#, ma è così ovvio che l'immagine sarebbe stata catturata).
EDIT: Il comando di compilazione è il seguente
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
(assembly referenziati rimosse per brevità).
Beh, io uso il "rilascio" di default costruire profilo in VS2010, quindi presumo che sto costruendo in realtà nella modalità di rilascio. La finestra di output dice "Build started: Project: FSharpLib, Configuration: Release Any CPU". Se cambio in "debug" ottengo MSIL completamente diverso come previsto. –
Sto testando con F # 1.9.7.8 e la riga di comando. Se non passo/debug, non ottengo un nop. –
Ho aggiornato la domanda con la riga di comando per la compilazione e ho provato a compilare utilizzando fsc.exe direttamente. Stesso risultato Secondo la finestra di output VS2010b2 non viene fornito con il compilatore più recente in quanto riporta un numero di versione di F # versione 1.9.7.4. Potrebbe essere la differenza? –