Подтвердить что ты не робот

"вложенные, если" против "если" и "производительность с использованием F #

Следующий код приводит к 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
4b9b3361

Ответ 1

Я получил MSIL от ildasm, который я отправлю здесь для того, чтобы кто-то из них (не раз) - это сообщество wiki time:

Быстрый (только сравнительные строки 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

Slow:

//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

С одной стороны, версия С# того же времени имеет одинаковые сроки для обеих версий.

Одна вещь, которую я заметил при разборке, заключалась в том, что переменные F # были Program.i и Program.a, поэтому я не уверен, есть ли какие-то помехи в F #, которых нет в С#.

Ответ 2

Отправлено: Don Syme:

Да, мы заметили поток и записали проблему. Это не совсем ошибка (код выполняется правильно), но было бы неплохо получить здесь эквивалентный перформанс.