小测试了一下nodejs,java,c++的百万次循环速度,请大神指正。
发布于 7 年前 作者 showen 32136 次浏览 最后一次编辑是 4 年前

nodejs代码如下:

//nodeJS
console.time('forNode');
var j=0;
for(var i=0;i<1000000;i++){
 j += (i/2+i)/2;
}
console.log("j="+j)
console.timeEnd('forNode');

//C++ for  nodejs
console.time('forC++');
var hello = require('./build/Release/hello.node').hello;

console.log("j="+hello)
console.timeEnd('forC++');

其中hello.node是编译好的,代码如下:

#include <node.h>
#include <v8.h>

using namespace v8;

double forfunc(){
  double i,j=0;
  for(i=0;i<1000000;i++){
   j += (i/2+i)/2;
  };
  return j;
}


void init(Handle<Object> target) {
  double j;
  j = forfunc();
  target->Set(String::NewSymbol("hello"),Number::New(j));

}
NODE_MODULE(hello, init);

java代码如下:

public class HowT {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		long start = System.currentTimeMillis();
		long j=0;
		for (int i=0;i<1000000;i++)
		{
			j+=(i/2+i)/2;
		}
		long end = System.currentTimeMillis();
		System.out.println("j="+j);
                System.out.println("forJava: " + (end - start));
	}
}

node、node调用c++f结果如下:

E:\快盘\我的代码\node.js\addon>node addon.js
j=374999625000
forNode: 12ms
j=374999625000
forC++: 6ms

java结果如下:

G:\win7\Program Files\Dropbox>java HowT
j=374999250000
forJava: 14

要说明的是:除了由于第一次加载hello.node要花多一点时间外,用node循环所需的时间波动在11-13ms,node for c++循环所需时间波动在5-7ms,java循环所需的时间波动在13-15ms。

另外如果循环体内是简单计算的话(例如简单的累加),node所需要的时间会少于node for c++,v8威武啊。

测试机器:win7 64位系统 8G内存 cpu:Intel® Core™2 Quad CPU Q8200 @ 2.33GHz 2.33GHz

15 回复

貌似 java 是整数运算, C++ 是浮点运算,Nodejs … 本质上应该也是浮点运算吧。

嗯 我考虑过这个问题 本来c++要用long的 但是不知道为什么会溢出 nodejs通过v8会转成c++里面的类型吧 刚才把java里面的long修改成double试了一下了 运算时间也基本没变 其实我也只是粗略的演示一下nodejs的速度是非常快的 这种简单的并演示没有考虑编译器、解释器对代码的优化 以前总是有种印象:像js这样的脚本语言肯定会慢很多 其实语言的快慢和语言没有什么关系 主要是是编译器、解释器能做到多快

同层次中理想状态下,解释型不可能快于原生编译执行。其实java也是解释型,但是有JIT。nodejs的优势还是简易快速,这个层面上php python ruby 才是竞争对手,他们刚起步时都带有这些标签。谈性能。。。还是过段日子吧。。。

对于V8来说,javascript已经不是解析型的,已经是编译型的了,只是第一次编译成机器码需要一点时间

@151263 ok 大概浏览了一下各个js引擎的技术。确实v8也用jit的等方式优化的。但是挺奇怪的,njs为何测试下来的情况比java慢很多?。 连vertx都比nodejs综合性能高。

@wfeng007

传说是因为JS代码太灵活,很多情况下无法利用JIT充分优化

@liuyanghejerry

我又观察了一下nodejs所谓性能高的说法。貌似都指向io(尤其是网络),说单线程异步事件处理之类的。我真的很无语,java早在08年之前java1.4就已经是nio机制了。像mina之类很早就已经是反应堆模式了。现在几乎所有webserver底层都是nio+threadpool实现。java天生具有完美的多线程模型,同时能够充分利用多cpu能力。这种。。。。

老实说nodejs的现阶段真正最大优势其实是“开发便捷”。包括语言基础,大量的模块包,统一且不小的社区等。

@wfeng007nodejs中的io操作是基于事件、异步执行的,不会阻塞,这也是nodejs最大的优势,如果说代码执行速度的话脚本语言怎么来说都会比静态语言、基于虚拟机的解释型语言差那么一点,就像汇编语言会比c的执行速度快好几倍一样,但是在做应用层的时候谁还会用汇编呢,现在的网络程序构架的性能瓶颈主要在io上,基于事件的异步单线程nodejs很容易应付高并发、高频率io操作的需求,其实根本没有必要拿这些东西进行比较,各有各的优势,本人以上的测试只是闲的蛋疼的测试。另外,如果要评价一个东西的优势什么的是要深入了解之后才能去评论的,我不赞同你的说的javascript比较简单,javascript是被前端人员用烂了,javascript是非常灵活的,说实话比java复杂多了,前端人员有多少去深入了解原型链、call的用法呢,还有你说的大量模块包,现在nodejs的包根本就算不上多,只是包的发布速度比较快而已,而且现在的包比较杂、乱。最后说一句,如果是做底层的就好好搞c、c++,如果只是做上层应用的话,找到一个最合适合需求的技术就好了,如果你要做一个w级别的并发需求,选nodejs吧~~~

@wfeng007

你说的很对,node最主要还是为网站前后端开发者准备的,在异步模型上没有什么特别大的突破,不过正因为这样node也变得非常易于使用。在node用户层当中无需操心锁的问题,也无需操心竞态。当然近年来基于协程的并发模式也很受青睐,不过那又是另一个话题了。

Java是把大刀,和Java做比较,应该搬出C#才对。

@showen 我说的简单是指,一般使用比较简单。入门写出个可以跑的东西比较简单,一两句话能实现java十几行的功能。一个初学者可以很省力的写出java初学者需要很花力气完成的东西。 还有js的是脚本,脚本天生无法写复杂。些复杂了没法维护。

另外,如果你认为语言为了灵活而灵活,为了复杂而复杂我就无语了。java自己都吃了灵活的亏,java访问数据库不下几十种框架和写法,api都各有特点,用户自己选够灵活吧,然后呢?

nodejs包还不够?那再多就会步java的后尘。。。 阿猫阿狗都写一个 框架出来然后互相重复。你说你到底选哪个?选的不对怎么办?迁移?。。脚本语言做大规模整体迁移就是找死。。。

现在坐等吧。

@wfeng007脚本天生无法写复杂。些复杂了没法维护。 --不同意 javascript现在有包管理机制,可以实现继承机制,运行前的编译检查,等等,一样可以做复杂项目,很好维护 关键看怎么设计架构 javascript比java灵活,是语言层面上的灵活,不是API,也不是框架 比如,javascript用prototype等很简单的几行代码就可以实现AOP功能 而,java必须类似Spring那样使用什么动态代理,cglib等,多麻烦都懂得 还有,javascript的对象可以运行时动态的添加删除属性,而java不可以 还有java的class加载以后不能运行时删除,运行时替换,或者类似OSGI那样的机制,替换class很麻烦 而nodejs就很简单了

处理简单运算Java/C#会快些,你没看到PHP的跑分都很低吗?但为什么这么多低端服务器都用呢? 这跟大家经验完全不符,为什么会这样?

因为Web应用从来都不是简单的,评价性能还需要看看他吃了多少内存,看看这个语言是不是容易被过度设计,复杂度是否容易失控,需要的团队规模有多大,维护成本有多高。

  1. 个人认为node.js的每M内存性能最佳,JS本身是一种非常简单的语言,使用复杂设计模式时不需要消耗太多性能,单线程对内存的消耗是完全可控制,可预知的。

  2. 当规模上去后JAVA/C#的复杂度会呈指数上升,但你会发现JS/PHP几乎呈线性……

  3. JS各模块的藕合数非常低,使用JS你会天生使用面向Library,面向模块的编程方式;使用JAVA/C#,非常容易将继承,多态,设计模式发挥到极限,写出超复杂有超强藕合关系的系统,这是语言特点决定的。

  4. JS产出效率较高,因此JS适合小团队使用, 而Java文件分散,开发,编码量均较高,不利于创业型公司,这也是为什么LinkedIn, Groupon起初使用Ruby的原因。

@151263 不同意的话能否举出,纯粹用脚本写出的复杂系统案例。复杂只是模块化。没见识过js的静态分析工具,你所谓编译检查不知道能到何种程度。很多东西必须在运行中才能确定的脚本,我对其能否进行静态分析抱有怀疑。

js服务端js很早就有了。模块化的或者动态脚本也不是js首创。所谓灵活的语言动态的语言只有nodejs么?从perl 到ruby python都是动态语言脚本语言,那又如何呢?

还有你拿 js的对象与 java的class比较你不觉得奇怪么?既然你说了class加载,那我认为你是指java平台,而不是java语言。 首先class运行时能不能删除你先确认一下,不用osgi同样可以做到。osgi只是标准而已。 第二,你说“替换class很麻烦而nodejs就很简单了”,是,java替换class是麻烦。那是js没有class概念。js不是面向对象是基于对象,他是脚本不是静态语言。

当然你可以喜欢脚本语言。不过就脚本语言本身来讲很早就有了,js不是第一个也不会是最后一个。但是为何没有完全取代静态语言?难道以前用静态语言不用动态语言的人都是白痴么?为何? 举个例子静态语言一般有类型概念,很多脚本没有,js就没有。在这种情况下复杂系统中我不认为维护成本会不高。 如,50人开发的系统没人需要至少写出20000行代码,且互相关联互相调用(业务要求)。你准备全靠文档定义接口么?50人能力还参差不齐,有的人能力估计发明第二个nodejs,有的人连module机制都搞不清楚。你确认你能组织起这样的团队使用js开发出一个复杂系统? 还有不要说“架构”两个字。java圈子中架构已经研究烂掉了。只说架构就是典型的为了设计而设计。java圈子里面就是这样。国内java圈子,04年就开始讨论poeaa了。nodejs的人研究过poeaa么?或者posa?另一方面讲,出这些书的时候没有脚本语言么?

老实说,nodejs现在的优势来看,基本的对手就是python php。

随便提一句,java平台上也有js实现引擎,不光有js还有python、ruby实现。某些还比native实现性能高,比如js实现。java平台的实现ringojs,common-js标准覆盖率比nodejs高。

再回到“灵活”这个词。你不觉得java里面还能嵌入js+各种脚本混合开发比你一个nodejs灵活么?单单说语言灵活,单语言能比过混合语言开发?虽然我觉得灵活过度反而出问题。js就是过度灵活,不知道是福是祸。

你试过字符串操作吗? node里面执行211~219毫秒 java里面完成相同功能执行122毫秒

var s = “尊敬的张飞您好,您的验证码是:212333,感谢您的使用”; var template = “尊敬的您好,您的验证码是:******,感谢您的使用”; var temp = template.split(/*+/); function compare(s, temp, index, fromindex) { var s2 = temp[index]; if (s2 === undefined) return true; var len = s2.length; s2 = s.indexOf(s2, fromindex); if (s2 < 0) return false; return compare(s, temp, ++index, len + s2); } var startDate = Date.now(); for (var i = 0; i < 1000000; i++) { compare(s, temp, 0, 0); } console.log(Date.now() - startDate);

====================================== 上面说错了,java里执行时间53~98,初学java,感觉java慢是慢在分层太多,调用其它对象开销很大

public void test() {
	long start=System.currentTimeMillis();
	String s = "尊敬的张飞您好,您的验证码是:212333,感谢您的使用";
	String template = "尊敬的**您好,您的验证码是:******,感谢您的使用";
	String[] temp = template.split("\\*+");;
	for(int j = 0; j < 1000000; j++) {
		compare(s, temp,0,0);
	}
	System.out.println(System.currentTimeMillis()-start+"=对比时间");
}

public boolean compare(String s,String[] temp, int index, int fromindex){
	if(index >= temp.length) return true;
	String s2 = temp[index];
	int s2len = s2.length();
	fromindex = s.indexOf(s2, fromindex);
	if (fromindex < 0) return false;
	return compare(s, temp, ++index, fromindex + s2len);
}
回到顶部