這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
大家都知道Node.js的單進程非阻塞模型適合於任務密集性(I/O)而不是計算密集型.那麼到底有多不適合計算呢?下面做一個簡單的測試.
測試硬體平台如下:
電腦型號 蘋果 Macmini6,2 Lunch Box
作業系統 Windows 8 Enterprise 64位 ( DirectX 11 )
處理器 英特爾 第三代酷睿 i7-3615QM @ 2.30GHz 四核
記憶體 16 GB ( 三星 DDR3 1600MHz )
主硬碟 APPLE HDD HTS541010A9E662 ( 1 TB )
軟體平台:
Node.js 0.10.21
Qt5.2 beta1
Golang 1.2 R3
測試方法:
每一趟計算斐波那契8次.總共10趟(一共80次)計算總時間.
Node.js 不使用cluster模組.測試代碼如下:
function fibo (n) {return n > 1 ? fibo(n - 1) + fibo(n - 2) : 1;}var n = 8;function back(){if(!--n) {return console.timeEnd('total time');}}console.time('total time');for(var i = 0; i < 8; ++i){process.nextTick(function(){console.log(fibo (40));back();});}
10次總時間132393ms
.....額有人會說有cluster模組可以以多個進程的方式處理,效率會提升.那我們來看看使用cluster之後的效果如何
//clustervar cluster = require('cluster');var numCPUs = 8; //我的cpu是四核八線程function fibo (n) {return n > 1 ? fibo(n - 1) + fibo(n - 2) : 1;}console.time('8 cluster');if (cluster.isMaster) {// Fork workers.for (var i = 0; i < numCPUs; i++) {cluster.fork();}var i = 8;cluster.on('exit', function(worker, code, signal) {if(!--i){console.timeEnd('8 cluster');process.exit(0);}});} else {console.log(fibo (40));process.exit(0);}
10次總時間30322ms
下面是Qt(C++)中做同樣的處理(多線程)
#include <QThread>#include <QDebug>#include <QTime>#include <QtConcurrent>int fibo(int n){return n > 1? fibo(n-1) + fibo(n-2):1;}int main(int argc, char *argv[]){QList<int> lists;for (int i = 0; i < 8; ++i){lists.append(40);}QTime start;start.start();QList<int> thumbnails = QtConcurrent::blockingMapped(lists, fibo);foreach (int i, thumbnails){qDebug() << i;}qDebug() <<"total time is : "<< start.elapsed();}
Debug編譯10次總時間14279ms
Release編譯10次總時間8280ms
還有一個單線程的也是做同樣的計算,代碼就不貼了只貼結果
Debug編譯10次總時間64864ms
Release編譯10次總時間37790ms
Golang單線程代碼如下:
package mainimport ("fmt""time")func fibonacci(num int) int {if num < 2 {return 1}return fibonacci(num-1) + fibonacci(num-2) //我不記得golang有沒有三目運算子了......}func main() {start := time.Now()for i := 0; i < 8; i++ {nums := fibonacci(40)fmt.Println(nums)}end := time.Now()fmt.Println("total time:", end.Sub(start).Nanoseconds()/1000/1000)}
十次總時間73910ms.
Golang 使用8線程計算:
package mainimport ("fmt""time""runtime")func fibonacci(num int) int {if num < 2 {return 1}return fibonacci(num-1) + fibonacci(num-2) //我不記得golang有沒有三目運算子了......}func main() {ch := make(chan int, 8)runtime.GOMAXPROCS(8)start := time.Now()for i := 0; i < 8; i++ {go func(){nums := fibonacci(40)ch <- nums} ()//fmt.Println(nums)}for i := 0; i < 8; i++{fmt.Println(<-ch)}end := time.Now()fmt.Println("total time:", end.Sub(start).Nanoseconds()/1000/1000)}
10次總時間14780ms
詳細測試結果如下:
無cluster |
8cluster |
8線程Debug |
8線程Release |
單線程Debug |
單線程Release |
Golang單線程 |
Golang 8線程 |
13212 |
3031 |
1502 |
847 |
6538 |
3804 |
7413 |
1443 |
13253 |
3029 |
1429 |
841 |
6473 |
3768 |
7371 |
1420 |
13233 |
3014 |
1429 |
810 |
6488 |
3812 |
7380 |
1442 |
13232 |
3044 |
1414 |
811 |
6467 |
3757 |
7420 |
1545 |
13465 |
2980 |
1466 |
818 |
6477 |
3782 |
7387 |
1507 |
13244 |
3018 |
1414 |
805 |
6504 |
3758 |
7377 |
1465 |
13213 |
3061 |
1414 |
831 |
6461 |
3771 |
7373 |
1494 |
13192 |
3025 |
1402 |
857 |
6512 |
3816 |
7391 |
1463 |
13143 |
3075 |
1398 |
801 |
6476 |
3747 |
7402 |
1503 |
13206 |
3045 |
1411 |
859 |
6468 |
3775 |
7396 |
1498 |
132393 |
30322 |
14279 |
8280 |
64864 |
37790 |
73910 |
14780 |
看資料不太直觀那看看下面的圖吧......
總結:
我們可以看到在計算效能上C++ > Golang > Node.js.
C++單核和多線程效率都差不多是Golang一倍
Golang單核和多線程效能差不多是Node.js的一倍
寫在最後:
本次並非全面的權威的測試,測試結果僅僅作為一方面的參考,並不能說明Node.js效率就是渣渣.而且Node.js我也是初學,代碼也有可能有誤.對於測試結果大家不要太過於介懷,仁者見仁智者見智.
回去了在我的24核伺服器上再跑一次看看結果怎麼樣.