【发布时间】:2016-03-05 08:28:17
【问题描述】:
在测试一个 JavaScript 项目的性能时,我注意到一个非常奇特的行为 - JavaScript 成员访问性能似乎受到它们所在范围的严重影响。我写了一些性能测试,结果不同 多个数量级。
我使用这些浏览器在 Windows 10 64 位上进行了测试:
- Google Chrome,版本 49.0.2623.75 m - 使用 V8 JavaScript engine
- Mozilla Firefox,版本 44.0.2 - 使用 SpiderMonkey JavaScript engine
- Microsoft Edge,版本 25.10586 - 使用 Chakra JavaScript engine
以下是我运行的最相关的测试及其各自的结果:
// Code running on global scope, accessing a variable on global scope
// Google Chrome: 63000 ms.
// Mozilla Firefox: 57000 ms.
// Microsoft Edge: 21000 ms.
var begin = performance.now();
var i;
for(i = 0; i < 100000000; i++) { }
var end = performance.now();
console.log(end - begin + " ms.");
// Code running on local scope, accessing a variable on global scope
// Google Chrome: 61500 ms.
// Mozilla Firefox: 47500 ms.
// Microsoft Edge: 22000 ms.
var begin = performance.now();
var i;
(function() {
for(i = 0; i < 100000000; i++) { }
})();
var end = performance.now();
console.log(end - begin + " ms.");
// Code running on local scope, accessing a variable on local scope
// Google Chrome: 50 ms.
// Mozilla Firefox: 28 ms.
// Microsoft Edge: 245 ms.
var begin = performance.now();
(function() {
var i;
for(i = 0; i < 100000000; i++) { }
})();
var end = performance.now();
console.log(end - begin + " ms.");
在本地和全局范围内运行的代码之间的差异在误差范围内,尽管 Firefox 在本地范围内运行似乎确实获得了相当一致的 20% 的性能提升。
最大的惊喜是在本地范围内访问变量,它在 Chrome 和 Firefox 上快了 1200 到 1600 倍,在 Edge 上快了 90 倍。
为什么会在三种不同的浏览器/JavaScript 引擎上出现这种情况?
【问题讨论】:
-
new Date().getTime()是一个非常糟糕的性能测量工具。使用 Performance API 获得更准确的读数。 -
本次测试使用内置的Date函数没有问题。
-
@MadaraUchiha 我更新了我的代码和测试结果以使用性能 API,它没有明显的效果。不过感谢您的提示!
-
你怎么能确定解释器没有完全优化循环呢?这似乎很可能会产生三个数量级的差异。
-
@torazaburo 因为增加循环长度
n次按比例增加执行时间n次。如果它已被优化,执行时间将是恒定的,接近 0。我将更新我的问题以反映这一点。
标签: javascript performance scope