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
- nodejs
- nodejs + cpp module
- python
- pypy: a fast, compliant alternative implementation of the Python language (2.7.1).
- perl
- php
- ruby
- lua
- luajit: a Just-In-Time Compiler for Lua.
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)
Language | Times | Position |
---|---|---|
c | 0m1.606s | #0 |
go | 0m1.769s | #1 |
node + cpp module | 0m2.216s | #2 |
luajit | 0m2.583s | #3 |
nodejs | 0m5.124s | #4 |
pypy | 0m7.562s | #5 |
lua | 0m34.492s | #6 |
python | 1m11.647s | #7 |
php | 1m28.198s | #8 |
perl | 2m34.658s | #9 |
ruby 1.9.3 | 4m40.790s | #10 |
ruby 1.8.5 | 4m41.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.
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”)
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;
}