2013-04-16 7 views
13

Il codice seguente restituisce slow1 = 1323 ms, slow2 = 1311 ms e fast = 897 ms. Come è possibile?"nidificato se" rispetto a "se" e prestazioni utilizzando F #

Qui: Nested or not nested if-blocks? accennano che

qualsiasi compilatore moderno, e con questo intendo qualsiasi cosa costruita negli ultimi 20 anni, compilerà questi per lo stesso codice.

let s = System.Diagnostics.Stopwatch() 
let mutable a = 1 
s.Start() 

for i in 0 .. 1000000000 do 
    if i < 0 then 
    if i < 0 then 
     a <- 4 

printfn "fast = %d" s.ElapsedMilliseconds 

s.Restart() 

for i in 0 .. 1000000000 do 
    if i < 0 && i < 0 then 
    a <- 4 

printfn "slow1 = %d" s.ElapsedMilliseconds 

s.Restart() 

for i in 0 .. 1000000000 do 
    if i < 0 & i < 0 then 
    a <- 4 

printfn "slow2 = %d" s.ElapsedMilliseconds 
+0

hai provato in modalità di rilascio? –

+1

Sì. Anche qualsiasi CPU, X86 e X64. In modalità debug entrambe le versioni diventano ugualmente lente (3083 ms). –

+0

Devo dire che il risultato ugualmente lento rende molto più "senso" dei diversi ... –

risposta

4

ho entrato in possesso della MSIL da ildasm, che vi posterò qui per qualcuno di approfondire (tempo) - è il momento comunità wiki:

veloce (solo il i linee di confronto come il resto identiche):

//000030: if i < 1000 then 
    IL_001f: ldloc.0 
    IL_0020: ldc.i4  0x3e8 
    IL_0025: bge.s  IL_003b 
//000031:  if i < 1000 then 
    IL_0027: ldloc.0 
    IL_0028: ldc.i4  0x3e8 
    IL_002d: bge.s  IL_0038 

lento:

//000039: if i < 1000 && i < 1000 then 
    IL_0084: ldloc.0 
    IL_0085: ldc.i4  0x3e8 
    IL_008a: bge.s  IL_0097 
    IL_008c: ldloc.0 
    IL_008d: ldc.i4  0x3e8 
    IL_0092: clt 
    IL_0094: nop 
    IL_0095: br.s  IL_0099 
    IL_0097: ldc.i4.0 
    IL_0098: nop 
    IL_0099: brfalse.s IL_00a4 

In una nota a margine, la versione C# della stessa ha lo stesso tempismo per entrambe le versioni.

Una cosa che ho notato nello smontaggio era che le variabili F # erano Program.i e Program.a, quindi non sono sicuro se c'è qualche interferenza dell'oggetto in F # che non c'è in C#.

+0

Il 'nop' non dovrebbe essere lì in una build ottimizzata – usr

+0

@usr non sono sicuro che hai ragione ... –

+0

Questo è l'output di un Release build con ottimizzazione attivata (VS2012) Non ci sono dettagli sulle ottimizzazioni, solo on o off –

4

E-mail da Don Syme:

Sì, abbiamo notato il filo e ha registrato un problema. Non è esattamente un bug (il codice viene eseguito correttamente), ma sarebbe sicuramente meglio ottenere un perfetto equivalente qui.

+1

Puoi dire a Don, che dal momento che la community di sviluppatori \ F # è ancora piuttosto piccola, e il team di sviluppo di F # sembra un gruppo di ragazzi simpatici (negli standard degli sviluppatori di compilatori), ci piacerebbe avere un po 'di attenzione personale :-) –