arrays - F#:为什么 Array.createZero 这么快?

标签 arrays f# initialization array-initialization

我有这个代码:

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 来执行,这将非常快。

关于arrays - F#:为什么 Array.createZero 这么快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24340843/

相关文章:

C# 从 byte[] 获取 string[]

c++ - 没有默认构造函数时,使用垃圾数据初始化对象

objective-c - 什么是 Objective-C "constructor"?

PHP Array_diff 当有重复的数组值时

php - 从字符串中获取单词 - PHP

javascript - 基于 Node JS 中的其他数组过滤/搜索 JavaScript 对象数组

generics - f# 可区分联合泛型

f# - 如何在 F# 中使用 Playwright Sharp 进行浏览器自动化

.net - 如何为F#应用程序编写退出处理程序?

c++ - 在C++中重新声明数组