大家都知道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之后的效果如何
//cluster var 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 main import ( "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 main import ( "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核服务器上再跑一次看看结果怎么样.
有疑问加站长微信联系(非本文作者)