var test = function () {
var i,
a,
startTime;
startTime = new Date().getTime();
for (i = 0; i < 3000000000; i = i + 1) {
a = i % 5;
}
console.log(a); //prevent dead code eliminiation
return new Date().getTime() - startTime;
};
var results = [];
for (var i = 0; i < 5; i = i + 1) {
results.push(test());
}
for (var i = 0; i < results.length; i = i + 1) {
console.log('Time needed: ' + results[i] + 'ms');
}
结果:
首次执行:
Time needed: 13654ms
Time needed: 32192ms
Time needed: 33167ms
Time needed: 33587ms
Time needed: 33630ms
第二次执行:
Time needed: 14004ms
Time needed: 32965ms
Time needed: 33705ms
Time needed: 33923ms
Time needed: 33727ms
第三次执行:
Time needed: 13124ms
Time needed: 30706ms
Time needed: 31555ms
Time needed: 32275ms
Time needed: 32752ms
从第一排跳到第二排的原因是什么?
我的设置:
Ubuntu 13.10
Google Chrome 36.0.1985.125(Mozilla Firefox 30.0提供相同类型的结果)
编辑:
我修改了代码,在语义上保持相同但内联所有内容。有趣的是,它不仅显着加快了执行速度,而且还在很大程度上消除了我上面描述的现象。尽管如此,轻微的跳跃仍然是显而易见的。
修改后的代码:
结果:
首次执行:
Time needed: 13786ms
Time needed: 14402ms
Time needed: 14261ms
Time needed: 14355ms
Time needed: 14444ms
第二次执行:
Time needed: 13778ms
Time needed: 14293ms
Time needed: 14236ms
Time needed: 14459ms
Time needed: 14728ms
第三次执行:
Time needed: 13639ms
Time needed: 14375ms
Time needed: 13824ms
Time needed: 14125ms
Time needed: 14081ms
答案 0 :(得分:1)
经过一些测试后,我认为我已经指出可能导致差异的原因。它必须与类型我认为。
有关 var i,
a = 0,
startTime;
var a = 0
为我提供了一个统一的结果,整体性能更快,另一方面var a = "0"
给我的结果与你的相同:第一个有点快。
我不知道为什么会这样。
答案 1 :(得分:0)
Google Chrome似乎将您的脚本执行分解为块,并为其他进程提供处理时间。在每次函数调用执行大约600ms之前,它不会引人注意。我用较小的数据子集进行了测试(如果我没记错的话,可以测试300000000。)
答案 2 :(得分:0)
以下只是一个伪答案,我希望社区可以更新。最初,这将是一个评论,但它变得太冗长,太快,因此需要作为答案发布。
在running a few tests中,我无法找到与console.log
使用的任何相关性。在OSX Safari中进行测试,我发现无论是否打印到控制台都存在问题。
我注意到的是一种模式。当我从你的初始起始值接近2147483648(2 ^ 31)时,有一个拐点。这很可能取决于用户的环境,但我发现了一个大约2147485000的拐点(尝试上面和下面的数字; 2147430000..2147490000)。在这个数字的某个地方,时间变得更加统一。
我真的希望它会是2 ^ 31 [确切],因为这个数字在计算机方面也很重要;它是long
整数的上限。但是,我的测试得出的数字略高于此数(原因不明)。除了确保交换文件没有被使用之外,我没有做任何其他的内存分析。
在我的设置中,它实际上正好是跳跃发生的2 ^ 31。我通过使用以下代码进行测试:
此信息可能支持Derek的初始化观察。
这只是一个想法,可能是一个延伸:
LLVM或其他可能正在执行一些前期优化。也许循环变量以int
开始,然后在一两次传递后,优化器注意到该变量变为long
。在尝试优化时,它会尝试将其设置为前期长,仅在这种情况下,它不是节省时间的优化,因为使用常规整数的性能优于从int到long的转换成本。 / em>的
如果答案在ECMAScript文档中的某处,我不会感到惊讶:)