13

次のコードはslow1 = 1323 ms、 、slow2 = 1311 msおよびになりfast = 897 msます。そんなことがあるものか?

ここ:ネストされているかネストされていない if ブロック? 彼らはそれについて言及します

最新のコンパイラ、つまり過去 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
4

2 に答える 2

4

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

遅い:

//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#バージョンは、両方のバージョンで同じタイミングです。

逆アセンブルで気づいたことの 1 つは、F# 変数が Program.i と Program.a だったことです。そのため、C# にはないオブジェクト干渉が F# にあるかどうかはわかりません。

于 2013-04-16T13:32:03.683 に答える