f#:为什么是数组?createZero这么快



我有这样的代码:

let timer = new System.Diagnostics.Stopwatch()
timer.Start()
Array.zeroCreate<int> 100000000
timer.Stop()
printfn "%ims" timer.ElapsedMilliseconds
timer.Reset()
timer.Start()
Array.create 100000000 0
timer.Stop()
printfn "%ims" timer.ElapsedMilliseconds

我对它进行了测试,得到了以下结果:

0ms
200ms

如何Array.zeroCreate创建数组这么快,它的所有元素都有默认值保证?在其他语言中,我知道没有这样的可能性(据我所知)。在其他语言中,我只知道数组的快速初始化,这些元素不保证具有默认值,因为它们可以在内存中初始化,而内存中存在一些垃圾。

谢谢!

所以我们可以去查找源代码:

    [<CompiledName("ZeroCreate")>]
    let zeroCreate count =
        if count < 0 then invalidArg "count" (SR.GetString(SR.inputMustBeNonNegative))
        Microsoft.FSharp.Primitives.Basics.Array.zeroCreateUnchecked count

    [<CompiledName("Create")>]
    let create (count:int) (x:'T) =
        if count < 0 then invalidArg "count" (SR.GetString(SR.inputMustBeNonNegative))
        let array = (Microsoft.FSharp.Primitives.Basics.Array.zeroCreateUnchecked count : 'T[])
        for i = 0 to Operators.Checked.(-) count 1 do // use checked arithmetic here to satisfy FxCop
            array.[i] <- x
        array

所以从这里我们可以看到Create做了更多的工作-所以它更慢。

我们可以更深入地找到底层函数:

// The input parameter should be checked by callers if necessary
let inline zeroCreateUnchecked (count:int) =
    (# "newarr !0" type ('T) count : 'T array #)

这基本上只是执行CIL newarr指令。

这个指令完全可以通过调用适当大小的calloc来执行,这将是令人难以置信的快。

相关内容

  • 没有找到相关文章