Wednesday, November 28, 2007

Holy Shmoly, C++ smokes Haskell away!!

From a blog, Haskell smokes Python and Ruby away!

My machine: SysInfo: Linux 2.6.22-ARCH | Pentium III (Coppermine) 797.426 MHz | Bogomips: 1596.4 | Mem: 368/504M [||||||||||] | Diskspace: 9.41G Free: 2.94G | Procs: 57 | Uptime: 39 mins | Load: 0.30 0.38 0.27 | Vpenis: 27.7 cm | Screen: nVidia Corporation NV5M64 [RIVA TNT2 Model 64/Model 64 Pro] (rev 15) @ 1280x1024 (24 bpp) | eth0: In: 1.70M Out: 0.47M

C++ version:

#include <iostream>
template <unsigned N> unsigned fib() { return fib<N-1>() + fib<N-2>(); }
template <> unsigned fib<0>() { return 0; }
template <> unsigned fib<1>() { return 1; }
template <unsigned N>
void eval() {
    std::cout<<"n="<<N<<" => "<<fib<N>()<<std::endl;
    eval<N-1>();
}
template <> void eval<0>() { std::cout<<"n=0 => 0"<<std::endl; }
int main() { eval<36>(); }

Initial test:

$ time (g++ fib.cpp && ./a.out) #computation done during compilation
real    0m2.832s
user    0m2.656s
sys     0m0.157s

This includes parsing, calculating fibonacci numbers, and output to console.

Now, onto Haskell:

$ ghc --make Fib.hs
$ time ./Fib
real    0m31.343s
user    0m28.068s
sys     0m0.167s

Compilation time isn't included. But wow.. 31 seconds. Haskell program was like this:

module Main where
import Text.Printf
import Control.Monad

fib :: Int -> Int
fib 0 = 0
fib 1 = 1
fib n = fib (n-1) + fib (n-2)

main = forM_ [0..35] $ \i ->
    printf "n=%d => %d\n" i (fib i)

I'm not sure if it's a proper way to do. I don't know about forM_. And printf might be also expensive.

Anyways testing with optimization flag:

$ ghc --make -O3 Fib.hs
$ time ./Fib
real    0m2.566s
user    0m2.530s
sys     0m0.007s

This doesn't include compilation time. And it beats C++.

Let's run C++ version after compilation. Cheating, I know.

$ g++ fib.cpp
$ time ./a.out
real    0m1.278s
user    0m1.253s
sys     0m0.003s

$ g++ -O3 fib.cpp
$ time ./a.out
real    0m0.023s
user    0m0.007s
sys     0m0.007s

Hehe. lolbye.