以下代码会产生slow1 = 1323 ms
,slow2 = 1311 ms
和fast = 897 ms
。怎么可能?
在这里:Nested or not nested 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
答案 0 :(得分:4)
我已经从ildasm获得了MSIL,我将在这里发帖给某人详细说明(没时间) - 这是社区维基时间:
快速(仅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
慢速:
//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
另一方面,两个版本的C#版本具有相同的时序。
我在反汇编中注意到的一件事是F#变量是Program.i和Program.a,所以我不确定F#中是否有某些对象干扰,而C#中没有。
答案 1 :(得分:4)
来自Don Syme的电子邮件:
是的,我们已经注意到该主题并记录了一个问题。这不是一个错误(代码正确执行),但在这里获得等效的启动肯定会很好。