“展开”反复循环“复制和粘贴”循环体可以改善或减少表现。
结果取决于...
- ...你的 JavaScript 引擎
- ...循环体中的代码
- ...你的代码有多么完善的文档(不是开玩笑!)
让我们使用 Google 流行的 V8 JavaScript 引擎(Chrome、Node)来分析性能:
普通循环:
var count = 0;
for (var i = 0; i < 10; i++) {
count += 1;
}
展开的循环:
var count = 0;
count += 1;
count += 1;
...
count += 1;
Result:展开的循环大约是速度提高 10 倍.
但是如果我们循环 1000 次而不是 10 次呢?然后展开的循环突然变得超过慢 10 倍比普通循环好!
如果我们用函数调用交换简单的算术表达式会怎么样?
普通循环:
function f() {
return 1;
}
var count = 0;
for (var i = 0; i < 10; i++) {
count += f();
}
展开的循环:
var count = 0;
count += f();
count += f();
...
count += f();
Result:展开的循环大约是速度提高 50%.
但是如果我们向函数 f 添加注释怎么办?
function f() {
// bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla
return 1;
}
突然,展开的循环大约是慢 20%!
这是为什么?
- 当解析正文包含少于 600 个字符(包括空格和注释)的函数时,V8 会自动内联代码。
- V8执行栈上替换当一个函数“卡在”一个很长的循环中时。
关于最后一个例子:通过添加超过 600 个字符的长注释,我们可以防止 V8 在解析期间内联函数 f,并依赖于运行时优化功能(例如“栈上替换”),该功能针对整个函数和循环,但不手动重复代码。
正如您所看到的,很难预测这种微观“优化”的结果。所以最好不要这样做 - 除非您针对特定 JS 引擎的特定版本。
See https://jsfiddle.net/Lj9v7c2m/对于性能分析 - 根据您的计算机/浏览器/版本,您可能会得到不同的结果。