原文地址:http://blog.csdn.net/slug302/article/details/14521261
大家都知道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('<span style="font-family:Arial,Helvetica,sans-serif">total time</span>');
-
- for(var i = 0; i < 8; ++i){
- process.nextTick(function(){
- console.log(fibo (40));
- back();
- });
- }
10次总时间132393ms
.....额有人会说有cluster模块可以以多个进程的方式处理,效率会提升.那我们来看看使用cluster之后的效果如何
-
- var cluster = require('cluster');
- var numCPUs = 8;
- function fibo (n) {
- return n > 1 ? fibo(n - 1) + fibo(n - 2) : 1;
- }
- console.time('8 cluster');
- if (cluster.isMaster) {
-
- 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)
- }
-
- 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
- } ()
-
- }
-
- 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核服务器上再跑一次看看结果怎么样.