【发布时间】:2012-11-08 00:04:23
【问题描述】:
声明:这是微基准,如果您对该主题感到不满意,请不要评论诸如“过早优化是邪恶的”之类的引用。
示例是针对 x64 的版本、.Net4.5 Visual Studio 2012 F# 3.0 并在 windows 7 x64 中运行
分析后,我缩小了我的一个应用程序的瓶颈,所以我想提出这个问题:
观察
如果for in 循环或Seq.iter 内部没有循环,那么很明显它们的速度相似。 (更新 2 与更新 4)
如果for in 循环或Seq.iter 中存在循环,则Seq.iter 似乎是for in 的2 倍。 (更新与更新3)奇怪吗? (如果在 fsi 中运行,它们会相似)
如果是针对anycpu,运行在x64,时间上没有区别。所以问题变成了:如果目标是 x64,Seq.iter (update3) 将提高 2 倍速度
花费时间:
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
源代码:
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
【问题讨论】:
-
请检查您的缩进。
-
对此类问题的标准答案是
seq.iter具有函数调用开销 -
@JohnPalmer 我在问为什么 seq.iter 更快,而不是更慢......
-
@RamonSnir 我的缩进有什么问题?
-
反汇编显示没有差异,据我所知,这应该会导致差异 - 唯一的可能是一些启发式不同,因为
Seq.iter版本的代码要少得多,因为方法只是内部循环 - 也许 JIT 摆脱了一些计算?
标签: f#