3

私はこのコードを持っています:

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て配列を非常に高速に作成し、すべての要素がデフォルト値を持つことが保証されますか? 他の言語では、そのような可能性はありません (私の知る限り)。他の言語では、ガベージが存在するメモリ内で初期化できるため、要素がデフォルト値を持つことが保証されていない配列の高速初期化についてしか知りません。

ありがとう!

4

1 に答える 1

6

したがって、ソースを調べるだけです。

    [<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 #)

これは基本的に CILnewarr命令を実行するだけです。

この命令は、適切なサイズで呼び出すことで実行できcalloc、信じられないほど高速です。

于 2014-06-21T11:32:18.353 に答える