原文地址: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();
- });
- }
.....额有人会说有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();
- }
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)
- }
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)
- }
详细测试结果如下:
无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核服务器上再跑一次看看结果怎么样.
有疑问加站长微信联系(非本文作者)