Javascript perf,奇怪的结果

时间:2015-02-05 18:16:27

标签: javascript node.js

我想知道在我的nodejs项目中使用javascript编写代码的更好方法是什么,所以我这样做了:

function clas(){
}

clas.prototype.index = function(){
	var i = 0;
	while(i < 1000){
		i++;
	}
}

var t1 = new clas();
var f = 0;
var d1 = new Date();
while(f < 1000){
	t1.index();
	f++;
}
console.log("t1: "+(new Date()-d1)+"ms");


f=0;
var d2 = new Date();
while(f < 1000){
	var t2 = new clas();
	t2.index();
	f++;
}
console.log("t2: "+(new Date()-d2)+"ms");

在我的浏览器上,第一个和第二个是相同的... 1ms和nodejs,我有t1 = 15ms和t2 = 1ms,为什么?为什么第一个花费的时间比第二个多,因为他没有初始化我的课程?

2 个答案:

答案 0 :(得分:1)

以下是几个问题。您的示例表明您在基准测试或系统性能方面的经验很少。这就是为什么我推荐brushing up on the very basics,直到你有了更多的感觉,不要尝试优化。 Optimizing prematurely is generally a bad thing。如果由一个对性能优化一无所知的人来完成,那么“优化”最终会成为纯粹的噪音:有些是工作,有些则不是,几乎是随机的。

为了完整性,以下是您的测试用例出现的一些问题:

首先,1000不足以进行性能测试。您希望以数百万的顺序进行迭代,以便CPU实际花费大量时间。

其次,对于基准测试,您需要use a high performance timer。节点为什么给你15ms的原因是因为它使用粗粒度系统计时器,其最小单位大约为15ms,这很可能对应于系统的scheduling granularity

第三,关于你的实际问题:如果没有必要,在你的循环中分配一个新对象几乎总是一个糟糕的性能选择。引擎盖下有很多内容,包括堆分配的可能性。但是,在您的简单情况下,大多数运行时可能会优化掉大部分开销,原因有两个:

  1. 您的测试用例过于简单,优化器可以轻松优化简单的代码段,但在实际情况下却难度更大。
  2. 您的测试用例为transient。如果优化器足够智能,它将检测到它,并且它将跳过整个循环。

答案 1 :(得分:0)

这是因为node对代码进行了jut-in-time(JIT)编译优化。

通过JIT优化,我们的意思是节点在执行时尝试优化代码。

所以......第一次调用该函数需要花费更多时间,节点意识到它可以优化这个for循环,因为它什么都不做。而对于所有其他调用,执行优化循环。

所以...后续电话会花费更少的时间。

您可以尝试更改订单。第一次通话将花费更多时间。

在某些浏览器中,代码会提前优化(即在运行代码之前)。