为什么javascript中的斐波那契计算比haskell快?

为什么javascript中的斐波那契计算比haskell快?,javascript,c,performance,haskell,fibonacci,Javascript,C,Performance,Haskell,Fibonacci,正如您在下面的示例中所看到的,javascript/node比haskell快得多。 但是haskell是基于C编译的。在这个例子中,您可以看到C是最快的。相比之下,哈斯克尔怎么会这么慢呢 由节点执行的JS: $time node fib.js 1346269 实际0M0045S 用户0M0040S 系统0M0004S 哈斯克尔: $ghc-o fibh fib.hs $time./fibh 1346269 真正的0M0178S 用户0M0168S 系统0M0000S c: 这只是因为GMPIn

正如您在下面的示例中所看到的,javascript/node比haskell快得多。
但是haskell是基于C编译的。在这个例子中,您可以看到C是最快的。相比之下,哈斯克尔怎么会这么慢呢

由节点执行的JS: $time node fib.js
1346269
实际0M0045S
用户0M0040S
系统0M0004S

哈斯克尔: $ghc-o fibh fib.hs
$time./fibh
1346269
真正的0M0178S
用户0M0168S
系统0M0000S

c:
这只是因为GMP
Integer
s和machine
Int
s之间的差异:

% cat fib.hs
fib :: Int -> Int -- N.B. default is `Integer`
fib 0 = 1
fib 1 = 1
fib n = fib (n-1) + fib (n-2)

main = print (fib 30)


% ghc -O2 fib.hs && time ./fib
1346269
./fib  0.01s user 0.00s system 87% cpu 0.013 total

如果您将
-O2
添加到编译器中会怎么样?Haskell可能也默认使用任意精度的算术…您的测试太短,没有意义,而且由于代码非常有限,您实际上只测试了每种语言的一小部分。此外,这是计算斐波那契数的糟糕方法。使用递归算法计算
fib(30)
需要大约270万次调用
fib()
,并占用大量堆栈空间。实际上,您所测试的是这些语言在异常情况下保存和检索其操作状态的能力。在正常运行时,这不是比较它们性能的一种现实方法。除了上面提到的所有内容之外:当添加
-O2
时,您是否强制重新编译
-fforce-recomp
?否则,重新编译可能什么也没做。此外,通过添加类型签名
fib::Int->Int
,应该可以使其更快,因为否则该类型将默认为
Integer
,这将大大降低速度。不仅如此,还包括算法是否为尾部递归。显示了不同的算法。
fib 0 = 1
fib 1 = 1
fib n = fib (n-1) + fib (n-2)

main = print (fib 30)
#include <stdio.h>

int fib(int n) {
    if (n == 0 || n == 1) 
        return 1;

    return fib(n-1)+fib(n-2);
}

int main() {
    int f = fib(30);
    printf("cfib: %i\n", f);
}
$ ghc -O2 -o fibh fib.hs
$ time ./fibh
1346269
real 0m0,166s
user 0m0,160s
sys 0m0,004s
% cat fib.hs
fib :: Int -> Int -- N.B. default is `Integer`
fib 0 = 1
fib 1 = 1
fib n = fib (n-1) + fib (n-2)

main = print (fib 30)


% ghc -O2 fib.hs && time ./fib
1346269
./fib  0.01s user 0.00s system 87% cpu 0.013 total