“嵌套if”与“if和”使用F#的性能

时间:2013-04-16 12:33:50

标签: c# performance if-statement f# cil

以下代码会产生slow1 = 1323 msslow2 = 1311 msfast = 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

2 个答案:

答案 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的电子邮件:

  

是的,我们已经注意到该主题并记录了一个问题。这不是一个错误(代码正确执行),但在这里获得等效的启动肯定会很好。