fibonacci(40) benchmark
发布于 13 年前 作者 fengmk2 8995 次浏览 最后一次编辑是 8 年前

<p><a href=“http://teddziuba.com/2011/10/node-js-is-cancer.html”>Node.js is Cancer</a> show a wrong way to use nodejs.<br />But the test code <strong><a href=“http://en.wikipedia.org/wiki/Fibonacci”>Fibonacci</a></strong> is so funny.<br />I implement the <strong>fibonacci function</strong> in other <strong><a href=“http://en.wikipedia.org/wiki/Dynamic_programming_language”>Dynamic Languages</a></strong> for comparison testing.</p> <br/> <br/><h2>Languages</h2> <br/> <br/><h3>Dynamic</h3> <br/> <br/><ul> <br/><li><a href=“http://nodejs.org”>nodejs</a></li> <br/><li><a href=“http://kkaefer.github.com/node-cpp-modules”>nodejs + cpp module</a></li> <br/><li><a href=“http://python.org”>python</a></li> <br/><li><a href=“http://pypy.org/”>pypy</a>: a fast, compliant alternative implementation of the Python language (2.7.1). </li> <br/><li><a href=“http://perl.org”>perl</a> </li> <br/><li><a href=“http://www.php.net/”>php</a></li> <br/><li><a href=“http://www.ruby-lang.org/”>ruby</a></li> <br/><li><a href=“http://www.lua.org/”>lua</a></li> <br/><li><a href=“http://luajit.org/”>luajit</a>: a Just-In-Time Compiler for Lua.</li> <br/></ul> <br/> <br/><h3>Static</h3> <br/> <br/><ul> <br/><li><a href=“http://en.wikipedia.org/wiki/C_(programming_language)”>c</a></li> <br/><li><a href=“http://golang.org/”>go</a></li> <br/></ul> <br/> <br/><p>If you want to help add more dynamic languagues, please leave the <strong>implement code</strong> in comments.</p> <br/> <br/><h2>Results</h2> <br/> <br/><p>(^_^) c > go > luajit > nodejs > pypy > lua > python > php > perl > ruby1.9.3 > ruby1.8.5 (T_T)</p> <br/> <br/><table> <br/> <tr><th>Language</th><th>Times</th><th>Position</th></tr> <br/> <tr><td style=“color: green;”>c</td><td>0m1.606s</td><td>#0</td></tr> <br/> <tr><td style=“color: green;”>go</td><td>0m1.769s</td><td>#1</td></tr> <br/> <tr><td style=“color: green;”>node + cpp module</td><td>0m2.216s</td><td>#2</td></tr> <br/> <tr><td style=“color: green;”>luajit</td><td>0m2.583s</td><td>#3</td></tr> <br/> <tr><td style=“color: green;”>nodejs</td><td>0m5.124s</td><td>#4</td></tr> <br/> <tr><td style=“color: green;”>pypy</td><td>0m7.562s</td><td>#5</td></tr> <br/> <tr><td>lua</td><td>0m34.492s</td><td>#6</td></tr> <br/> <tr><td>python</td><td>1m11.647s</td><td>#7</td></tr> <br/> <tr><td>php</td><td>1m28.198s</td><td>#8</td></tr> <br/> <tr><td>perl</td><td>2m34.658s</td><td>#9</td></tr> <br/> <tr><td style=“color: red;”>ruby 1.9.3</td><td>4m40.790s</td><td>#10</td></tr> <br/> <tr><td style=“color: red;”>ruby 1.8.5</td><td>4m41.942s</td><td>#11</td></tr> <br/></table> <br/> <br/><p><strong>lua</strong> use <em>local function</em> will get better performance.</p> <br/> <br/><h2>Test Codes</h2> <br/> <br/><h3>nodejs</h3> <br/> <br/><pre><pre><code>function fibonacci(n) { <br/> if (n < 2) { <br/> return 1; <br/> } <br/> return fibonacci(n - 2) + fibonacci(n - 1); <br/>} <br/> <br/>console.log(fibonacci(40)); <br/></pre></code></pre> <br/> <br/><p>run</p> <br/> <br/><pre><pre><code>$ time node fibonacci.js <br/>165580141 <br/> <br/>real 0m5.153s <br/>user 0m5.124s <br/>sys 0m0.012s <br/></pre></code></pre> <br/> <br/><h3>nodejs + cpp module</h3> <br/> <br/><p>cppfibonacci.cpp</p> <br/> <br/><pre><pre><code>#include <node/v8.h> <br/>#include <node/node.h> <br/> <br/>using namespace v8; <br/> <br/>int fibonacci(int n) { <br/> if (n < 2) { <br/> return 1; <br/> } <br/> return fibonacci(n - 1) + fibonacci(n - 2); <br/>} <br/> <br/>Handle<Value> Fibonacci(const Arguments& args) { <br/> HandleScope scope; <br/> <br/> if (args.Length() < 1) { <br/> return ThrowException(Exception::TypeError( <br/> String::New(“First argument must be a number”))); <br/> } <br/> Local<Integer> integer = args[0]->ToInteger(); <br/> int r = fibonacci(integer->Value()); <br/> <br/> return scope.Close(Integer::New®); <br/>} <br/> <br/>void RegisterModule(v8::Handlev8::Object target) { <br/> // Add properties to target <br/> NODE_SET_METHOD(target, “fibonacci”, Fibonacci); <br/>} <br/> <br/>// Register the module with node. <br/>NODE_MODULE(cppfibonacci, RegisterModule); <br/></pre></code></pre> <br/> <br/><p>wscript</p> <br/> <br/><pre><pre><code>#!/usr/bin/env python <br/> <br/>def set_options(ctx): <br/> ctx.tool_options(‘compiler_cxx’) <br/> <br/>def configure(ctx): <br/> ctx.check_tool(‘compiler_cxx’) <br/> ctx.check_tool(‘node_addon’) <br/> <br/>def build(ctx): <br/> t = ctx.new_task_gen(‘cxx’, ‘shlib’, ‘node_addon’) <br/> <br/> t.source = [‘cppfibonacci.cpp’] <br/> <br/> # Must be same as first parameter in NODE_MODULE. <br/> t.target = ‘cppfibonacci’ <br/></pre></code></pre> <br/> <br/><p>cppfibonacci.js</p> <br/> <br/><pre><pre><code>var fibonacci = require(’./build/default/cppfibonacci’).fibonacci; <br/>console.log(fibonacci(40)); <br/></pre></code></pre> <br/> <br/><p>run</p> <br/> <br/><pre><pre><code>$ node-waf configure <br/>$ node-waf build <br/>$ time node cppfibonacci.js <br/>165580141 <br/> <br/>real 0m2.224s <br/>user 0m2.216s <br/>sys 0m0.008s <br/></pre></code></pre> <br/> <br/><h3>python2.4.3 && python2.6.7 && pypy1.7</h3> <br/> <br/><pre><pre><code>def fibonacci(n): <br/> if n < 2: <br/> return 1 <br/> return fibonacci(n - 2) + fibonacci(n - 1) <br/> <br/>print fibonacci(40) <br/></pre></code></pre> <br/> <br/><p>run</p> <br/> <br/><pre><pre><code>$ time python2.4.3 fibonacci.py <br/>165580141 <br/> <br/>real 1m11.667s <br/>user 1m11.647s <br/>sys 0m0.002s <br/> <br/>$ time python2.6.7 fibonacci.py <br/>165580141 <br/> <br/>real 1m9.837s <br/>user 1m9.792s <br/>sys 0m0.006s <br/> <br/>$ time ./pypy-1.7/bin/pypy fibonacci.py <br/>165580141 <br/> <br/>real 0m7.608s <br/>user 0m7.562s <br/>sys 0m0.031s <br/></pre></code></pre> <br/> <br/><h3>perl</h3> <br/> <br/><pre><pre><code>sub fibonacci { <br/> my $n = shift; <br/> if ($n < 2) { <br/> return 1; <br/> } <br/> return fibonacci($n - 2) + fibonacci($n - 1); <br/>} <br/> <br/>print fibonacci(40), “\n”; <br/></pre></code></pre> <br/> <br/><p>run</p> <br/> <br/><pre><pre><code>$ time perl fibonacci.pl <br/>165580141 <br/> <br/>real 2m34.777s <br/>user 2m34.658s <br/>sys 0m0.004s <br/></pre></code></pre> <br/> <br/><h3>php</h3> <br/> <br/><pre><pre><code><?php <br/> <br/>function fibonacci($n) { <br/> if ($n < 2) { <br/> return 1; <br/> } <br/> return fibonacci($n - 2) + fibonacci($n - 1); <br/>} <br/> <br/>echo fibonacci(40)."\n"; <br/> <br/>?> <br/></pre></code></pre> <br/> <br/><p>run</p> <br/> <br/><pre><pre><code>$ time php fibonacci.php <br/> <br/>165580141 <br/>real 1m28.364s <br/>user 1m28.198s <br/>sys 0m0.039s <br/></pre></code></pre> <br/> <br/><h3>ruby1.8.5 && ruby1.9.3</h3> <br/> <br/><pre><pre><code>def fibonacci(n) <br/> if n < 2 <br/> return 1 <br/> end <br/> return fibonacci(n - 2) + fibonacci(n - 1) <br/>end <br/> <br/>puts fibonacci(40) <br/></pre></code></pre> <br/> <br/><p>run</p> <br/> <br/><pre><pre><code>$ time ruby1.8.5 fibonacci.rb <br/>165580141 <br/> <br/>real 5m43.132s <br/>user 4m41.942s <br/>sys 1m0.653s <br/> <br/>$ time ruby1.9.3 fibonacci.rb <br/>165580141 <br/> <br/>real 5m41.714s <br/>user 4m40.790s <br/>sys 1m0.661s <br/></pre></code></pre> <br/> <br/><h3>lua && luajit</h3> <br/> <br/><pre><pre><code>function fibonacci(n) <br/> if n < 2 then <br/> return 1 <br/> end <br/> return fibonacci(n - 2) + fibonacci(n - 1) <br/>end <br/> <br/>io.write(fibonacci(40), “\n”) <br/></pre></code></pre> <br/> <br/><p>run</p> <br/> <br/><pre><pre><code>$ time ./lua-5.1.4/src/lua fibonacci.lua <br/>165580141 <br/> <br/>real 0m34.514s <br/>user 0m34.492s <br/>sys 0m0.004s <br/> <br/>$ time ./LuaJIT-2.0.0-beta9/src/luajit fibonacci.lua <br/>165580141 <br/> <br/>real 0m2.598s <br/>user 0m2.583s <br/>sys 0m0.001s <br/></pre></code></pre> <br/> <br/><p>local function should be faster:</p> <br/> <br/><pre><pre><code>local function fibonacci(n) <br/> if n < 2 then <br/> return 1 <br/> end <br/> return fibonacci(n - 2) + fibonacci(n - 1) <br/>end <br/> <br/>io.write(fibonacci(40), “\n”) <br/> <br/>$ time ./lua-5.1.4/src/lua fibonacci.lua.local <br/>165580141 <br/> <br/>real 0m31.737s <br/>user 0m31.549s <br/>sys 0m0.001s <br/> <br/>$ time ./LuaJIT-2.0.0-beta9/src/luajit fibonacci.lua.local <br/>165580141 <br/> <br/>real 0m2.227s <br/>user 0m2.225s <br/>sys 0m0.001s <br/></pre></code></pre> <br/> <br/><h3>c</h3> <br/> <br/><pre><pre><code>#include <stdio.h> <br/> <br/>int fibonacci(n) { <br/> if (n < 2) { <br/> return 1; <br/> } <br/> return fibonacci(n - 2) + fibonacci(n - 1); <br/>} <br/> <br/>int main() { <br/> printf("%d\n", fibonacci(40)); <br/> return 0; <br/>} <br/></pre></code></pre> <br/> <br/><p>run</p> <br/> <br/><pre><pre><code>$ gcc fibonacci.c <br/>$ time ./a.out <br/>165580141 <br/> <br/>real 0m3.434s <br/>user 0m3.427s <br/>sys 0m0.000s <br/></pre></code></pre> <br/> <br/><p>Compilation with optimization:</p> <br/> <br/><pre><pre><code>$ gcc -O2 fibonacci.c <br/>$ time ./a.out <br/>165580141 <br/> <br/>real 0m1.607s <br/>user 0m1.606s <br/>sys 0m0.001s <br/></pre></code></pre> <br/> <br/><h3>go</h3> <br/> <br/><pre><pre><code>package main <br/> <br/>import “fmt” <br/> <br/>func fibonacci(n int) int{ <br/> if (n < 2) { <br/> return 1 <br/> } <br/> return fibonacci(n - 2) + fibonacci(n - 1) <br/>} <br/> <br/>func main() { <br/> fmt.Println(fibonacci(10)) <br/>} <br/></pre></code></pre> <br/> <br/><p>run</p> <br/> <br/><pre><pre><code>$ 6g fibonacci.go <br/>$ 6l fibonacci.6 <br/>$ time ./6.out <br/>165580141 <br/> <br/>real 0m1.770s <br/>user 0m1.769s <br/>sys 0m0.001s <br/></pre></code></pre> <br/> <br/><h2>Conclusion</h2> <br/> <br/><p><strong>nodejs</strong> is very <strong>FAST</strong>. <br /><strong>luajit</strong> 2X faster than nodejs, <strong>Shocking</strong>.</p> <br/>

8 回复

lua &jit lua <br/> <br/>function fibonacci(n,acc1,acc2) <br/> if n == 0 then <br/> return acc1 <br/> end <br/> return fibonacci(n - 1,acc2,acc1+acc2) <br/>end <br/> <br/>io.write(fibonacci(40,1,1), “\n”)

very interesting!

lua很厲害啊

How about C++ meta programming, it’s a bit of cheating :-) <br/> <br/>$ g++ fibonacci.cc <br/>$ time ./a.out <br/>165580141 <br/> <br/>real 0m0.003s <br/>user 0m0.001s <br/>sys 0m0.002s <br/> <br/> <br/>#include <br/> <br/>template <br/>struct fibonacci { <br/> enum { Result = fibonacci::Result + fibonacci::Result }; <br/>}; <br/> <br/>template <br/>struct fibonacci { <br/> enum { Result = 1 }; <br/>}; <br/> <br/>template <br/>struct fibonacci { <br/> enum { Result = 1 }; <br/>}; <br/> <br/>int main(int argc, char *argv[]) <br/>{ <br/> printf("%d\n", fibonacci::Result); <br/> return 0; <br/>}

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

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

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

跑测试的机器配置如何?为什么差距这么大。 <br/> <br/>sam@samqiu-desktop:/data/ruby$ time ruby fibonacci.rb <br/>165580141 <br/> <br/>real 0m42.010s <br/>user 0m41.819s <br/>sys 0m0.052s <br/>sam@samqiu-desktop:/data/ruby$ time ruby fibonacci.rb <br/>165580141 <br/> <br/>real 0m41.976s <br/>user 0m41.779s <br/>sys 0m0.012s

回到顶部