2013-04-16 12 views
13

Poniższy kod jest wynikiem slow1 = 1323 ms, slow2 = 1311 ms i fast = 897 ms. Jak to możliwe?"zagnieżdżony, jeśli" w porównaniu z wydajnością "jeśli i" przy użyciu F #

tutaj: Nested or not nested if-blocks? wspomnieć, że

Każdy nowoczesny kompilator i przez to mam na myśli niczego zbudowany w ciągu ostatnich 20 lat, będzie kompilować je do tego samego kodu.

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

czy wypróbowałeś go w trybie zwolnienia? –

+1

Tak. Również dowolny procesor, X86 i X64. W trybie debugowania obie wersje stają się równie wolne (3083 ms). –

+0

Muszę powiedzieć, że równie powolny wynik ma o wiele bardziej "sens" niż te różne ... –

Odpowiedz

4

mam chwycić MSIL od ildasm, który wyślę tu kogoś do opracowania na (brak czasu) - nadszedł czas Wiki:

Szybki (tylko i linie porównania jak reszty są identyczne):

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

Powolne:

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

Na marginesie, wersja C# tego samego ma taki sam czas dla obu wersji.

Jedną z rzeczy, które zauważyłem podczas demontażu, było to, że zmiennymi F # były Program.i i Program.a, więc nie jestem pewien, czy są jakieś zakłócenia obiektu w F #, którego nie ma w C#.

+0

'nop' nie powinien być tam w zoptymalizowanej kompilacji – usr

+0

@usr im nie wiesz, czy masz rację ... –

+0

To jest wyjście Wydanie kompilacji z włączoną optymalizacją (VS2012) Nie ma żadnych szczegółów na temat optymalizacji, tylko włączanie i wyłączanie –

4

email z Don Syme:

Tak, zauważyliśmy nitkę i rejestrowane problem. To nie jest dokładnie błąd (kod wykonuje się poprawnie), ale na pewno dobrze byłoby uzyskać odpowiednik perf tutaj.

+1

Czy możesz powiedzieć Donowi, że skoro społeczność programistów i entuzjastów F # jest wciąż bardzo mała, a zespół programistów F # wydaje się być całkiem fajni faceci (w standardach programistów kompilatorów), chcielibyśmy zwrócić trochę uwagi :-) –