2013-04-16 8 views
13

Der folgende Code resultiert in slow1 = 1323 ms, slow2 = 1311 ms und fast = 897 ms. Wie ist das möglich? Hier"verschachtelte wenn" versus "wenn und" Leistung unter Verwendung von F #

: Nested or not nested if-blocks? sie erwähnen, dass

Jeder moderne Compiler, und dass ich alles in den letzten 20 Jahren gebaut bedeuten, werden diese auf den gleichen Code kompilieren.

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

haben Sie es im Freigabemodus versucht? –

+1

Ja. Auch jede CPU, X86 und X64. Im Debug-Modus werden beide Versionen gleichermaßen langsam (3083 ms). –

+0

Ich muss sagen, dass das ebenso langsame Ergebnis viel mehr "Sinn" macht als die verschiedenen ... –

Antwort

4

ich halten, die MSIL von ildasm habe, was ich hier posten für jemanden (keine Zeit) zu erarbeiten auf - es ist Community Wiki Zeit:

Fast (nur die i Vergleichsleitungen wie der Rest sind identisch):

//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 

Slow:

//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 

Nebenbei bemerkt, C# -Version der gleichen hat das gleiche Timing für beide Versionen.

Eine Sache, die ich in der Demontage bemerkte, war, dass die F # Variablen Program.i und Program.a waren, also bin ich mir nicht sicher, ob es eine Objektinterferenz in F # gibt, die nicht in C# ist.

+0

Der 'nop' sollte nicht in einem optimierten Build da sein. – usr

+0

@ usr ich bin nicht sicher, du hast Recht ... –

+0

Das ist die Ausgabe von a Build mit eingeschalteter Optimierung (VS2012) Es gibt keine Details über Optimierungen, nur ein oder aus –

4

E-Mail von Don Syme:

Ja, haben wir den Faden bemerkt und ein Problem aufgezeichnet. Es ist nicht genau ein Fehler (der Code wird korrekt ausgeführt), aber es wäre definitiv gut, hier die gleiche Leistung zu erzielen.

+1

Könntest du Don sagen, dass die F # -Entwickler- und Enthusiasten-Community immer noch ziemlich klein ist und das F # -Entwicklungs-Team eine Menge zu sein scheint Ziemlich coole Jungs (in Compiler-Entwickler-Standards), wir würden uns gerne persönlich kümmern :-) –

Verwandte Themen