Я написал короткий генератор Set Mandelbrot в Haskell и на C и обнаружил, что версия C работает 20x быстрее, чем версия Haskell. Хотя я ожидал, что Haskell будет медленнее, я не ожидал большего, чем на порядок, учитывая, что я уже использую unboxed vectors и bangs, чтобы избежать чрезмерного thunking.
Профилирование показывает, что большая часть времени тратится на функцию go
следующего кода, которая на самом деле является просто циклом с некоторыми сравнениями, умножениями и дополнениями.
orbits limit radius a b = go 0 0 0
where
r2 = radius * radius
go !n !x !y
| n == limit = n
| x2 + y2 >= r2 = n
| otherwise = go (n + 1) (x2 - y2 + a) (2 * x * y + b)
where
x2 = x * x
y2 = y * y
В процессе выполнения требуется код C 0,9 секунды для запуска, и он принимает эквивалентный код Haskell 18 секунд. Они оба реализуют один и тот же алгоритм, и оба они генерируют один и тот же результат (графический файл PGM).
Исходный код Haskell находится здесь:
Код C здесь:
В чем может быть проблема, которая вызывает эту огромную разницу в производительности?