为什么Seq.iter和Seq.map这么慢?

时间:2012-06-03 22:47:47

标签: performance f# seq

在F#中考虑这段代码:

let n = 10000000
let arr = Array.init n (fun _ -> 0)

let rec buildList n acc i = if i = n then acc else buildList n (0::acc) (i + 1)
let lst = buildList n [] 0

let doNothing _ = ()
let incr x = x + 1

#time

arr |> Array.iter doNothing         // this takes 14ms
arr |> Seq.iter doNothing           // this takes 74ms

lst |> List.iter doNothing          // this takes 19ms
lst |> Seq.iter doNothing           // this takes 88ms

arr |> Array.map incr               // this takes 33ms
arr |> Seq.map incr |> Seq.toArray  // this takes 231ms!

lst |> List.map incr                // this takes 753ms
lst |> Seq.map incr |> Seq.toList   // this takes 2111ms!!!!

为什么iter模块上的mapSeq函数比ArrayList模块等效项慢得多?

1 个答案:

答案 0 :(得分:13)

一旦您呼叫Seq,您就会丢失类型信息 - 转移到列表中的下一个元素需要拨打IEnumerator.MoveNext。与Array相比,您只需增加一个索引,对于List,您只需取消引用指针即可。从本质上讲,您将为列表中的每个元素获得额外的函数调用。

由于类似原因,转换回ListArray也会降低代码速度