Я пытаюсь вычислить  Ackermann(4,1), и есть большая разница в производительности между разными языками/компиляторами. Ниже приведены результаты на моем  Core i7 3820QM, 16G, Ubuntu 12.10 64bit,
  C: 1.6s, gcc -O3 (с gcc 4.7.2)
int ack(int m, int n) {
  if (m == 0) return n+1;
  if (n == 0) return ack(m-1, 1);
  return ack(m-1, ack(m, n-1));
}
int main() {
  printf("%d\n", ack(4,1));
  return 0;
}
  OCaml: 3.6s, ocamlopt (с окамлом 3.12.1)
let rec ack = function
  | 0,n -> n+1
  | m,0 -> ack (m-1, 1)
  | m,n -> ack (m-1, ack (m, n-1))
in print_int (ack (4, 1))
  Стандарт ML: 5.1s mlton -codegen c -cc-opt -O3 (с mlton 20100608)
fun ack 0 n = n+1
  | ack m 0 = ack (m-1) 1
  | ack m n = ack (m-1) (ack m (n-1));
print (Int.toString (ack 4 1));
  Ракетка: 11,5 с racket (с ракеткой v5.3.3)
(require racket/unsafe/ops)
(define + unsafe-fx+)
(define - unsafe-fx-)
(define (ack m n)
  (cond
    [(zero? m) (+ n 1)]
    [(zero? n) (ack (- m 1) 1)]
    [else (ack (- m 1) (ack m (- n 1)))]))
(time (ack 4 1))
   Haskell: незавершенный, убитый системой после 22s ghc -O2 (с ghc 7.4.2)
  Haskell: 1,8 с ajhc (с ajhc 0.8.0.4)
main = print $ ack 4 1
  where ack :: Int -> Int -> Int
        ack 0 n = n+1
        ack m 0 = ack (m-1) 1
        ack m n = ack (m-1) (ack m (n-1))
Версия Haskell является единственной, которая не может завершиться должным образом, потому что она занимает слишком много памяти. Он замерзает мою машину и заполняет пространство подкачки перед тем, как его убили. Что я могу сделать, чтобы улучшить его без серьезного исправления кода?
EDIT. Я ценю некоторые из асимптотически умных решений, но они не совсем то, о чем я прошу. Это больше похоже на то, обрабатывает ли компилятор определенные шаблоны достаточно эффективным способом (стек, хвостовые вызовы, распаковка и т.д.), Чем вычисление функции ackermann.
EDIT 2. Как было отмечено несколькими ответами, это выглядит как ошибка в последних версиях GHC. Я пробую тот же код с AJHC и получаю гораздо лучшую производительность.
Большое спасибо:)