dlaczego Seq.iter jest 2x szybszy niż dla pętli, jeśli cel jest dla x64?
Zastrzeżenie: To jest mikro-benchmark, proszę nie komentować cytatów, takich jak „przedwczesna optymalizacja jest zła”, jeśli czujesz się niezadowolony z tematu.
Przykłady to wydanie przeznaczone dla x64, .Net4.5 Visual Studio 2012 F # 3.0 i uruchamiane w systemie Windows 7 x64
Po profilowaniu zawęziłem wąskie gardło jednej z moich aplikacji, więc chcę poruszyć to pytanie:
ObserwacjaJeśli w środku nie ma pętlifor in
pętla lubSeq.iter
, wtedy jest jasne, że oba mają podobną prędkość. (update2 vs update4)
Jeśli w środku jest pętlafor in
pętla lubSeq.iter
, wydaje sięSeq.iter
jest 2x szybszy niżfor in
. (aktualizacja a aktualizacja3) dziwne? (jeśli uruchomione w fsi byłyby podobne)
Jeśli jest przeznaczony dla anycpu i działa w x64, nie ma różnicy w czasie. Więc pytanie brzmi:Seq.iter (update3) zwiększyłoby 2x prędkość, jeśli celem jest x64
Zajęty czas:update: 00:00:11.4250483 // 2x as much as update3, why?
updatae2: 00:00:01.4447233
updatae3: 00:00:06.0863791
updatae4: 00:00:01.4939535
Kod źródłowy:open System.Diagnostics
open System
[<EntryPoint>]
let main argv =
let pool = seq {1 .. 1000000}
let ret = Array.zeroCreate 100
let update pool =
for x in pool do
for y in 1 .. 200 do
ret.[2] <- x + y
let update2 pool =
for x in pool do
//for y in 1 .. 100 do
ret.[2] <- x
let update3 pool =
pool
|> Seq.iter (fun x ->
for y in 1 .. 200 do
ret.[2] <- x + y)
let update4 pool =
pool
|> Seq.iter (fun x ->
//for y in 1 .. 100 do
ret.[2] <- x)
let test n =
let run = match n with
| 1 -> update
| 2 -> update2
| 3 -> update3
| 4 -> update4
for i in 1 .. 50 do
run pool
let sw = new Stopwatch()
sw.Start()
test(1)
sw.Stop()
Console.WriteLine(sw.Elapsed);
sw.Restart()
test(2)
sw.Stop()
Console.WriteLine(sw.Elapsed)
sw.Restart()
test(3)
sw.Stop()
Console.WriteLine(sw.Elapsed)
sw.Restart()
test(4)
sw.Stop()
Console.WriteLine(sw.Elapsed)
0 // return an integer exit code