Old*_*vec 13 c# performance f# cil if-statement
以下代码导致slow1 = 1323 ms,slow2 = 1311 ms和fast = 897 ms.怎么可能?
这里:嵌套或不嵌套的if-blocks?他们提到这一点
任何现代编译器,我的意思是在过去20年中构建的任何东西,都会将这些编译器编译成相同的代码.
let s = System.Diagnostics.Stopwatch()
let mutable a = 1
s.Start()
for i in 0 .. 1000000000 do
if i < 0 then
if i < 0 then
a <- 4
printfn "fast = %d" s.ElapsedMilliseconds
s.Restart()
for i in 0 .. 1000000000 do
if i < 0 && i < 0 then
a <- 4
printfn "slow1 = %d" s.ElapsedMilliseconds
s.Restart()
for i in 0 .. 1000000000 do
if i < 0 & i < 0 then
a <- 4
printfn "slow2 = %d" s.ElapsedMilliseconds
Run Code Online (Sandbox Code Playgroud)
我已经从 ildasm 获得了 MSIL,我将把它发布在这里供其他人详细说明(没有时间)——现在是社区 wiki 时间:
快速(只是i比较线,其余部分是相同的):
//000030: if i < 1000 then
IL_001f: ldloc.0
IL_0020: ldc.i4 0x3e8
IL_0025: bge.s IL_003b
//000031: if i < 1000 then
IL_0027: ldloc.0
IL_0028: ldc.i4 0x3e8
IL_002d: bge.s IL_0038
Run Code Online (Sandbox Code Playgroud)
慢的:
//000039: if i < 1000 && i < 1000 then
IL_0084: ldloc.0
IL_0085: ldc.i4 0x3e8
IL_008a: bge.s IL_0097
IL_008c: ldloc.0
IL_008d: ldc.i4 0x3e8
IL_0092: clt
IL_0094: nop
IL_0095: br.s IL_0099
IL_0097: ldc.i4.0
IL_0098: nop
IL_0099: brfalse.s IL_00a4
Run Code Online (Sandbox Code Playgroud)
顺便说一句,C# 版本的两个版本具有相同的时间。
我在反汇编中注意到的一件事是 F# 变量是 Program.i 和 Program.a,因此我不确定 F# 中是否存在一些 C# 中没有的对象干扰。