F#性能错误?

Sna*_*ark 3 performance f#

let test1fun x = [for i in 1..x-> i]

let test2fun x y= [for i in 1..x
                    do for i in 1..y-> i]

let  singlesearcher i =
    let rec searcher j agg =
        if j > i 
        then agg 
        else searcher (j+1) (i::agg)
    searcher 1 []


let  doublesearcher i j =
    let rec searcher k l agg =
        if k > i 
        then searcher 1 (l+1) agg
        else if l > j 
             then agg
             else searcher (k+1) l ((k,l)::agg)
    searcher 1 1 []
Run Code Online (Sandbox Code Playgroud)

对所有输入产生#time和10000执行上述操作

list comprehension/singlesearcher-> negligable
cross product -> 320
list comprehension crossproduct -> 630
Run Code Online (Sandbox Code Playgroud)

为什么嵌套列表理解超过功能版本的两倍?

Yin*_*Zhu 6

是.列表理解通常比直接使用F#list或array慢.(在我的机器上,我也找到了与你相似的时间.)

让我们看看它们是如何实现的.列表理解版本实际上非常复杂:

  1. 序列/ IEnumerable<int>使用理解语法创建.这只是一个懒惰的序列,这里花的时间很少.

  2. 然后通过使用类似的东西将此序列转换为F#List Seq.toList.实际时间在这里度过.有很多HasNext MoveNextswitch (state)类似代码在这里执行.有这么多函数调用,你不能指望它快速.

功能版本doublesearcher已正确优化为尾递归.这是比列表理解更直接的版本,并且其中使用很少的函数调用.

如果操作不是很关键,通常我们不关心序列,列表或数组的这些小的性能差异.我想在你的例子中,这一代人无论如何都是一次性的.这两个时间不是一个大问题.对于其他情况,例如两个向量的点积,使用数组可以节省大量时间,因为此操作执行了很多次.