问题描述
在F#中考虑以下代码:
Consider this code in 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
模块上的iter
和map
函数比Array
和List
模块等效项慢得多?
Why is the iter
and map
functions on the Seq
module so much slower than the Array
and List
module equivalents?
推荐答案
一旦调用Seq
,您将丢失类型信息-移至列表中的下一个元素需要调用IEnumerator.MoveNext
.与Array
相比,您只增加了一个索引,而对于List
,您可以仅取消引用了一个指针.本质上,您将获得列表中每个元素的额外功能调用.
Once you call in to Seq
you lose the type information - moving to the next element in the list requires a call to IEnumerator.MoveNext
. Compare to for Array
you just increment an index and for List
you can just dereference a pointer. Essentially, you are getting an extra function call for each element in the list.
出于类似原因,转换回List
和Array
的速度也会降低代码
The conversions back to List
and Array
also slow the code down for similar reasons
这篇关于为什么Seq.iter和Seq.map这么慢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!