list - 为什么 F# 列表范围比 for 循环慢这么多?

标签 list f#

我很惊讶 List 范围在下面的例子中慢了多少。在我的机器上,for 循环快了 8 倍左右。

是否首先创建了 10,000,000 个元素的实际列表?如果是这样,是否有原因(除了尚未完成)为什么编译器无法对其进行优化?

open System
open System.Diagnostics

let timeFunction f v =
    let sw = Stopwatch.StartNew()
    let result = f v
    sw.ElapsedMilliseconds

let length = 10000000

let doSomething n =
    (float n) ** 0.1 |> ignore

let listIter n =
    [1..length] |> List.iter (fun x -> doSomething (x+n))

let forLoop n = 
    for x = 1 to length do
        doSomething (x+n)

printf "listIter   : %d\n" (timeFunction listIter 1)  // c50
GC.Collect()
printf "forLoop    : %d\n" (timeFunction forLoop 1)  // c1000
GC.Collect()

最佳答案

使用 ILSpy,listIter看起来像这样:

public static void listIter(int n)
{
    ListModule.Iterate<int>(
        new listIter@17(n), 
        SeqModule.ToList<int>(
            Operators.CreateSequence<int>(
                Operators.OperatorIntrinsics.RangeInt32(1, 1, 10000000)
            )
        )
    );
}

以下是涉及的基本步骤:
  • RangeInt32创建一个 IEnumerable (莫名其妙地被 CreateSequence 包裹了)
  • SeqModule.ToList从该序列构建一个列表
  • listIter@17的一个实例(你的 lambda)是新的
  • ListModule.Iterate遍历列表,为每个元素调用 lambda

  • 对比 forLoop ,这看起来与您所写的没有太大区别:
    public static void forLoop(int n)
    {
        for (int x = 1; x < 10000001; x++)
        {
            int num = x + n;
            double num2 = Math.Pow((double)num, 0.1);
        }
    }
    

    ...否 IEnumerable 、lambda(自动内联)或列表创建。正在完成的工作量可能存在显着差异。

    编辑

    出于好奇,这里是 list 的 FSI 时间安排, seq , 和 for循环版本:
    listIter - Real: 00:00:03.889, CPU: 00:00:04.680, GC gen0: 57, gen1: 51, gen2: 6  
    seqIter  - Real: 00:00:01.340, CPU: 00:00:01.341, GC gen0:  0, gen1:  0, gen2: 0  
    forLoop  - Real: 00:00:00.565, CPU: 00:00:00.561, GC gen0:  0, gen1:  0, gen2: 0
    

    and the seq version for reference:

    let seqIter n =
        {1..length} |> Seq.iter (fun x -> doSomething (x+n))
    

    关于list - 为什么 F# 列表范围比 for 循环慢这么多?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12841704/

    相关文章:

    python - 如果我颠倒 zip 列表的顺序,为什么我会得到两个不同的词典

    f# - `fun` 和 `function` 关键字有什么区别?

    f# - 在f#中向列表添加内容

    f# - 更喜欢 XPlot 还是 F# 图表?

    python列表转换为表格

    java - 打印深度列表的内容?

    在列表元素内复制以制作嵌套列表

    f# - F# 项目中缺少 System.Data

    f# - 如何使用FsUnit检查歧视工会的情况?

    c# - 无法在 C# 中将一个列表附加到另一个列表...尝试使用 AddRange