fibonacci(40) benchmark

Node.js is Cancer show a wrong way to use nodejs.
But the test code Fibonacci is so funny.
I implement the fibonacci function in other Dynamic Languages for comparison testing.

Languages

Dynamic

Static

If you want to help add more dynamic languagues, please leave the implement code in comments.

Results

(^_^) c > go > luajit > nodejs > pypy > lua > python > php > perl > ruby1.9.3 > ruby1.8.5 (T_T)

LanguageTimesPosition
c0m1.606s#0
go0m1.769s#1
node + cpp module0m2.216s#2
luajit0m2.583s#3
nodejs0m5.124s#4
pypy0m7.562s#5
lua0m34.492s#6
python1m11.647s#7
php1m28.198s#8
perl2m34.658s#9
ruby 1.9.34m40.790s#10
ruby 1.8.54m41.942s#11

lua use local function will get better performance.

Test Codes

nodejs

function fibonacci(n) {
  if (n < 2) {
    return 1;
  }
  return fibonacci(n - 2) + fibonacci(n - 1);
}

console.log(fibonacci(40));

run

$ time node fibonacci.js
165580141

real  0m5.153s
user  0m5.124s
sys 0m0.012s

nodejs + cpp module

cppfibonacci.cpp

#include 
#include 

using namespace v8;

int fibonacci(int n) {
  if (n < 2) {
    return 1;
  }
  return fibonacci(n - 1) + fibonacci(n - 2);
}

Handle Fibonacci(const Arguments& args) {
    HandleScope scope;

    if (args.Length() < 1) {
        return ThrowException(Exception::TypeError(
            String::New("First argument must be a number")));
    }
    Local integer = args[0]->ToInteger();
    int r = fibonacci(integer->Value());

    return scope.Close(Integer::New(r));
}

void RegisterModule(v8::Handle target) {
    // Add properties to target
    NODE_SET_METHOD(target, "fibonacci", Fibonacci);
}

// Register the module with node.
NODE_MODULE(cppfibonacci, RegisterModule);

wscript

#!/usr/bin/env python

def set_options(ctx):
  ctx.tool_options('compiler_cxx')

def configure(ctx):
  ctx.check_tool('compiler_cxx')
  ctx.check_tool('node_addon')

def build(ctx):
  t = ctx.new_task_gen('cxx', 'shlib', 'node_addon')

  t.source = ['cppfibonacci.cpp']

  # Must be same as first parameter in NODE_MODULE.
  t.target = 'cppfibonacci'

cppfibonacci.js

var fibonacci = require('./build/default/cppfibonacci').fibonacci;
console.log(fibonacci(40));

run

$ node-waf configure
$ node-waf build
$ time node cppfibonacci.js
165580141

real  0m2.224s
user  0m2.216s
sys 0m0.008s

python2.4.3 && python2.6.7 && pypy1.7

def fibonacci(n):
    if n < 2:
        return 1
    return fibonacci(n - 2) + fibonacci(n - 1)

print fibonacci(40)

run

$ time python2.4.3 fibonacci.py
165580141

real  1m11.667s
user  1m11.647s
sys 0m0.002s

$ time python2.6.7 fibonacci.py
165580141

real  1m9.837s
user  1m9.792s
sys 0m0.006s

$ time ./pypy-1.7/bin/pypy fibonacci.py
165580141

real  0m7.608s
user  0m7.562s
sys 0m0.031s

perl

sub fibonacci {
    my $n = shift;
    if ($n < 2) {
      return 1;
    }
    return fibonacci($n - 2) + fibonacci($n - 1);
}

print fibonacci(40), "\n";

run

$ time perl fibonacci.pl
165580141

real  2m34.777s
user  2m34.658s
sys 0m0.004s

php


run

$ time php fibonacci.php

165580141
real  1m28.364s
user  1m28.198s
sys 0m0.039s

ruby1.8.5 && ruby1.9.3

def fibonacci(n)
  if n < 2
    return 1
  end
  return fibonacci(n - 2) + fibonacci(n - 1)
end

puts fibonacci(40)

run

$ time ruby1.8.5 fibonacci.rb
165580141

real  5m43.132s
user  4m41.942s
sys 1m0.653s

$ time ruby1.9.3 fibonacci.rb
165580141

real  5m41.714s
user  4m40.790s
sys 1m0.661s

lua && luajit

function fibonacci(n)
  if n < 2 then
    return 1
  end
  return fibonacci(n - 2) + fibonacci(n - 1)
end

io.write(fibonacci(40), "\n")

run

$ time ./lua-5.1.4/src/lua fibonacci.lua 
165580141

real  0m34.514s
user  0m34.492s
sys 0m0.004s

$ time ./LuaJIT-2.0.0-beta9/src/luajit fibonacci.lua 
165580141

real  0m2.598s
user  0m2.583s
sys 0m0.001s

local function should be faster:

local function fibonacci(n)
  if n < 2 then
    return 1
  end
  return fibonacci(n - 2) + fibonacci(n - 1)
end

io.write(fibonacci(40), "\n")

$ time ./lua-5.1.4/src/lua fibonacci.lua.local
165580141

real  0m31.737s
user  0m31.549s
sys 0m0.001s

$ time ./LuaJIT-2.0.0-beta9/src/luajit fibonacci.lua.local
165580141

real  0m2.227s
user  0m2.225s
sys 0m0.001s

c

#include 

int fibonacci(n) {
  if (n < 2) {
    return 1;
  }
  return fibonacci(n - 2) + fibonacci(n - 1);
}

int main() {
  printf("%d\n", fibonacci(40));
  return 0;
}

run

$ gcc fibonacci.c
$ time ./a.out 
165580141

real  0m3.434s
user  0m3.427s
sys 0m0.000s

Compilation with optimization:

$ gcc -O2 fibonacci.c
$ time ./a.out 
165580141

real  0m1.607s
user  0m1.606s
sys 0m0.001s

@fool: How about C++ meta programming, it’s a bit of cheating

#include 

template
struct fibonacci {
    enum { Result = fibonacci::Result + fibonacci::Result };
};

template<>
struct fibonacci<1> {
    enum { Result = 1 };
};

template<>
struct fibonacci<0> {
    enum { Result = 1 };
};

int main(int argc, char *argv[])
{
    printf("%d\n", fibonacci<40>::Result);
    return 0;
}

run

$ g++ fibonacci.template.cpp 
$ time ./a.out
165580141

real  0m0.002s
user  0m0.001s
sys 0m0.001s

go

package main

import "fmt"

func fibonacci(n int) int{
  if (n < 2) {
    return 1
  }
  return fibonacci(n - 2) + fibonacci(n - 1)
}

func main() {
  fmt.Println(fibonacci(10))
}

run

$ 6g fibonacci.go
$ 6l fibonacci.6
$ time ./6.out
165580141

real  0m1.770s
user  0m1.769s
sys 0m0.001s

Conclusion

nodejs is very FAST.
luajit 2X faster than nodejs, Shocking.

posted @ 2011-12-14 22:21 MK2 阅读(...) 评论(...) 编辑 收藏