fibonacci(40) benchmark
发布于 3年前 作者 fengmk2 2963 次浏览

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 <node/v8.h>

#include <node/node.h>

using namespace v8;

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

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

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

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

void RegisterModule(v8::Handle<v8::Object> 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



<?php


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

echo fibonacci(40)."\n";

?>


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 <stdio.h>


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


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.


8 回复

lua &jit lua

function fibonacci(n,acc1,acc2)
if n == 0 then
return acc1
end
return fibonacci(n - 1,acc2,acc1+acc2)
end

io.write(fibonacci(40,1,1), “\n”)

very interesting!

lua很厲害啊

How about C++ meta programming, it’s a bit of cheating :-)

$ g++ fibonacci.cc
$ time ./a.out
165580141

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


#include

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

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

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

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

尖括号都没了……
上面的代码看这里 http://ideone.com/66zj4

哈哈,这么高级,不过这不像是递归执行的吧?这个测试只是想测试所有语言的递归性能来做对比。。。如果改成非递归形式,就没意思了。。。

其实也是递归,不过是在编译期完成。靠着编译期运算C++可以在很多性能测试里作弊……

跑测试的机器配置如何?为什么差距这么大。

sam@samqiu-desktop:/data/ruby$ time ruby fibonacci.rb
165580141

real 0m42.010s
user 0m41.819s
sys 0m0.052s
sam@samqiu-desktop:/data/ruby$ time ruby fibonacci.rb
165580141

real 0m41.976s
user 0m41.779s
sys 0m0.012s

回到顶部