Следующие две программы Haskell для вычисления n-го члена последовательности Фибоначчи имеют значительно отличающиеся характеристики:
fib1 n =
case n of
0 -> 1
1 -> 1
x -> (fib1 (x-1)) + (fib1 (x-2))
fib2 n = fibArr !! n where
fibArr = 1:1:[a + b | (a, b) <- zip fibArr (tail fibArr)]
Они очень близки к математически идентичным, но fib2
использует нотацию списка для memoize своих промежуточных результатов, а fib1
имеет явную рекурсию. Несмотря на возможность кэширования промежуточных результатов в fib1
, время выполнения становится проблемой даже для fib1 25
, предполагая, что рекурсивные шаги всегда оцениваются. Предоставляет ли ссылочная прозрачность что-либо для производительности Haskell? Как я могу узнать заранее, если это будет или не будет?
Это просто пример того, о чем я беспокоюсь. Я хотел бы услышать любые мысли о преодолении трудностей, присущих рассуждениям о производительности лениво исполняемого, функционального языка программирования.
Резюме: Я принимаю ответ 3lectrologos, потому что тот факт, что вы не так много рассуждаете о производительности языка, как о вашей оптимизации компилятора, кажется чрезвычайно важным в Haskell - больше чем на любом другом языке, с которым я знаком. Я склонен сказать, что важность компилятора - это фактор, который отличает рассуждения о производительности в ленивых, функциональных языках, от рассуждений о производительности любого другого типа.
Добавление: Любое событие, которое может возникнуть по этому вопросу, возможно, захочет посмотреть слайды из Johan Tibell говорить о высокой производительности Haskell.