JavaScript性能,怪异的结果

我想知道什么是更好的方式来在我的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,为什么? 为什么第一次比第二次花更多的时间,因为他没有初始化我的课程?

这里有几个问题。 您的示例显示您在基准testing或系统性能方面的经验很less。 这就是为什么我build议刷新基本知识 ,直到你有更多的感觉,不要尝试优化。 过早优化通常是一件坏事 。 如果某人对性能优化一无所知,那么“优化”最终会变成纯粹的噪音:有些工作,有些工作几乎不随意。

为了完整起见,下面是一些你的testing用例是错误的:

首先, 1000是不够的性能testing。 你想要为你的CPU做数百万次的迭代,实际上花费了大量的时间。

其次,对于基准testing,您希望使用高性能计时器 。 节点为什么给你15ms的原因是因为它使用了一个粗粒度的系统定时器,其最小单位大约是15ms,这很可能对应于你的系统的调度粒度 。

第三,关于你的实际问题:在循环中分配一个新的对象,如果没有必要的话,对于性能来说几乎总是一个不好的select。 有很多事情正在进行,包括堆分配的可能性。 但是,在你的简单情况下,大多数运行时间可能会优化大部分开销,原因有两个:

  1. 你的testing用例太简单了,优化器可以很容易地优化简单的代码段,但是在实际情况下要困难得多。
  2. 你的testing案例是暂时的 。 如果优化器足够聪明,它会检测到,并且会跳过整个循环。

这是因为节点对代码进行了延时(JIT)编译优化。

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

所以…第一个调用函数需要更多的时间,节点意识到它可以优化这个for-loop,因为它什么也不做。 而对于所有其他调用,优化的循环被执行。

所以…随后的电话会花费更less的时间。

您可以通过更改顺序来尝试。 第一个电话会花费更多的时间。

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