Есть ли причина, почему F # не достаточно умны, чтобы оптимизировать следующий код?
Я был бы удивлен, если компилятор F # сможет оптимизировать этот случай. В конце, fn
- это поле записи, которое предназначено для хранения данных, а не для выполнения функций.
Даже на нестатических элементах компилятор не может встроить их, поскольку эти члены ограничены изменением среды. Объявляя привязку let
, у вас есть преимущество статической среды, и компилятор может встроить в некоторые простые случаи.
Действительно, в этом примере функция fn
встроена (добавление inline
не меняет время работы). Медленным примером является цена, которую вы платите за более мощную конструкцию.
Всякий раз, когда вы должны создать запись функций, помните, что интерфейсы и выражения объекта лучшие альтернативы (меньше накладные расходы, лучше IntelliSense):
type Data2 =
abstract fn : int * int -> int
let data2 =
{ new Data2 with
member __.fn (x, y) = fn (x, y) }
s.Restart()
for i in 0 .. 1000000000 do
a <- data2.fn(i, i)
printfn "a bit slow = %d" s.ElapsedMilliseconds
Это результат я получил, выполнив в F # Interactive 64 -битовый:
fast = 614
slow = 7498
a bit slow = 2765
Так подход интерфейс на основе является 3x быстрее, чем подход на основе записей и 3x медленнее, чем метод инлайн.
Я думаю, что ваш вопрос не совсем прав. Правильный вопрос - почему _doesn't_ установщик оптимизирует его, а не почему _can't_ он оптимизирует его. – mydogisbox