几乎相同的方法之间的极好的性能差异

use*_*567 2 compiler-construction optimization performance f#

在处理项目时,我意外地注意到只有一个额外(未使用)参数的相同方法运行甚至比另一个运行快十倍,并且启用了优化.

type Stream () =
    static member private write (x, o, a : byte[]) = (for i = 0 to 3 do a.[o + i] <- byte((x >>> 24 - i * 8) % 256)); 4
    static member private format f x l = Array.zeroCreate l |> fun a -> (f(x, 0, a) |> ignore; a)
    static member private format1 f x l o = Array.zeroCreate l |> fun a -> (f(x, 0, a) |> ignore; a)
    static member Format (value : int) =  Stream.format (fun (x: int, i, a) -> Stream.write(x, i, a)) value 4
    static member Format1 (value : int) =  Stream.format1 (fun (x: int, i, a) -> Stream.write(x, i, a)) value 4
Run Code Online (Sandbox Code Playgroud)

在测试中,Stream.Format1运行速度比快很多Stream.Format,虽然私有成员之间的唯一区别Stream.format,并Stream.format1仅仅是o说法,而且这是方法本身使用.

编译器如何以不同的方式处理两种几乎相同的方法?

编辑:谢谢你的解释和抱歉的无知.

Tom*_*cek 8

问题是当你Format1用一个参数调用时,它只返回一个函数.它还没有进行实际的格式化.这意味着如果你比较以下的表现:

Stream.Format 42
Stream.Format1 42
Run Code Online (Sandbox Code Playgroud)

...然后你实际上比较了第一种情况下实际格式化(创建数组并在其中写入内容)的性能以及只返回函数值而不做任何事情的代码性能.

如果您没有使用任何o参数format1,那么您可以传入一些虚拟值,以实际评估函数并获得结果.然后你应该得到类似的表现:

Stream.Format 42
Stream.Format1 42 ()
Run Code Online (Sandbox Code Playgroud)