Consider this simple “benchmark”:
n :: Int
n = 1000
main = do
print $ length [(a,b,c) | a<-[1..n],b<-[1..n],c<-[1..n],a^2+b^2==c^2]
and appropriate C version:
#include <stdio.h>
int main(void)
{
int a,b,c, N=1000;
int cnt = 0;
for (a=1;a<=N;a++)
for (b=1;b<=N;b++)
for (c=1;c<=N;c++)
if (a*a+b*b==c*c) cnt++;
printf("%d\n", cnt);
}
Compilation:
- Haskell version is compiled as:
ghc -O2 triangle.hs(ghc 7.4.1) - C version is compiled as:
gcc -O2 -o triangle-c triangle.c(gcc 4.6.3)
Run times:
- Haskell: 4.308s real
- C: 1.145s real
Is it OK behavior even for such a simple and maybe well optimizable program that Haskell is almost 4 times slower? Where does Haskell waste time?
The Haskell version is wasting time allocating boxed integers and tuples.
You can verify this by for example running the haskell program with the flags
+RTS -s. For me the outputted statistics include:A straightforward encoding of the C version is faster since the compiler can use unboxed integers and skip allocating tuples:
See:
The running time of this version is
1.920svs.1.212sfor the C version.