【问题标题】:why is Seq.iter and Seq.map so much slower?为什么 Seq.iter 和 Seq.map 这么慢?
【发布时间】:2012-06-03 22:47:47
【问题描述】:

考虑一下 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!!!!

为什么Seq 模块上的itermap 函数比ArrayList 等效模块慢得多?

【问题讨论】:

    标签: performance f# seq


    【解决方案1】:

    一旦你调用Seq,你就会丢失类型信息——移动到列表中的下一个元素需要调用IEnumerator.MoveNext。与Array 相比,您只需增加一个索引,而对于List,您只需取消引用一个指针。本质上,您会为列表中的每个元素获得一个额外的函数调用。

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

    【讨论】:

    • 尽管您对实际原因可能是正确的。它并没有真正回答更深层次的问题。他们为什么选择使用 MoveNext。正如在 linq 库中所做的那样,您可以从类型检查开始,在列表或数组的情况下选择匹配的版本,那么大序列的差异就可以忽略了
    猜你喜欢
    • 2019-09-16
    • 2012-08-10
    • 1970-01-01
    • 1970-01-01
    • 2021-09-03
    • 2011-12-08
    • 1970-01-01
    • 2016-09-28
    • 2020-02-08
    相关资源
    最近更新 更多