Оптимизатор Haskell использует memoization для повторных вызовов функций в области?
Рассмотрим эту функцию:
f as = if length as > 100 then length as else 100
Поскольку функция чиста, очевидно, что длина будет одинаковой для обоих вызовов. Мой вопрос: оптимизатор Haskell переводит код выше в эквивалент следующего?
f as =
let l = length as
in if l > 100 then l else 100
Если это так, то какой уровень настройки позволяет? Если это не так, то почему? В этом случае отходы памяти не могут быть причиной, описанной в этом ответе, поскольку введенная переменная освобождается после завершения выполнения функции.
Обратите внимание, что это не дубликат этого вопроса из-за локальной области видимости и, следовательно, может иметь принципиально иной ответ.
Ответы
Ответ 1
GHC теперь делает несколько CSE по умолчанию, поскольку флаг -fcse
включен.
Вкл. по умолчанию.. Включает устранение общего суб-выражения оптимизация. Выключение этого параметра может быть полезно, если у вас есть небезопасные выраженияPerformIO, которые вы не хотите распространять.
Тем не менее, он консервативен из-за проблем с внедрением совместного использования (и, следовательно, утечки пространства).
Пропуск CSE получает бит лучше, хотя (и this).
Наконец, обратите внимание, что есть плагин для полной CSE.
Если у вас есть код, который может извлечь из этого выгоду.
Ответ 2
Даже в такой локальной настройке все же неясно, что введение совместного использования всегда является оптимизацией. Рассмотрим пример определения
f = if length [1 .. 1000000] > 0 then head [1 .. 1000000] else 0
против. этот
f = let xs = [1 .. 1000000] in if length xs > 0 then head xs else 0
и вы обнаружите, что в этом случае первое ведет себя намного лучше, так как каждый из вычислений, выполненных в списке, является дешевым, тогда как вторая версия приведет к тому, что список будет полностью развернут в памяти на length
, и его можно отбросить только после уменьшения head
.
Ответ 3
Дело, которое вы описываете, больше связано с устранением общего подвыражения, чем memoization, однако кажется, что GHC в настоящее время не делает этого ни потому, что непреднамеренный совлокальный доступ может привести к утечке пространства.