fla*_*404 5 javascript performance
从JavaScript代码中删除注释是否可以提高性能?
我意识到这不是很好的编程实践,因为评论构成了发展的内在组成部分.我只是想知道它们是否确实在编译期间增加了一些开销.
Eri*_* J. 11
无论是编译还是解释JavaScript,编译器/解释器都需要查看该行,确定它是注释,然后继续(或查看该行的某个区域).对于Web应用程序,还需要下载注释行.
所以,是的,有一些开销.
但是,我怀疑你能找到一个真实世界的情况,这种差异很重要.
如果要编译代码,则开销仅在编译运行期间,而不是在后续执行期间.
截至2016年9月24日,以下答案不再准确。
在此提交中删除了源长度启发式: https://github.com/v8/v8/commit/0702ea3000df8235c8bfcf1e99a948ba38964ee3#diff-64e6fce9a2a9948942eb00c7c1cb75f2
令人惊讶的答案是可能的!
正如 Eric 指出的那样,下载和解析方面存在开销,但这可能很小,在大多数情况下难以察觉。
然而,JavaScript 性能是一头难以驯服的危险野兽,并且注释至少还有一种其他方式可以影响性能。
现代(截至 2016 年)JavaScript 引擎(例如 V8)做了很多相当繁重的工作来确保高性能。这些引擎所做的事情之一称为 JIT——“即时”编译。JIT 编译包括许多复杂且有时不直观的步骤,其中之一是将适当的小函数内联到调用站点中。
内联意味着给定的代码如下:
function doIt(a, b) {
return (a + b) * 2;
}
function loop() {
var x = 1, y = 1;
var i;
for(i = 0; i < 100; ++i) {
x = doIt(x, y);
}
}
Run Code Online (Sandbox Code Playgroud)
编译器将执行与转换为以下代码相同的操作:
function loop() {
var x = 1, y = 1;
var i;
for(i = 0; i < 100; ++i) {
// the doIt call is now gone, replaced with inlined code
x = (x + y) * 2;
}
}
Run Code Online (Sandbox Code Playgroud)
JIT 编译器能够确定是否可以将调用替换doIt为函数体。这可以释放巨大的性能优势,因为它完全消除了函数调用的性能开销。
然而,JavaScript 引擎如何选择哪些函数适合内联呢?有许多标准,其中之一是函数的大小。理想情况下,这将是编译函数的大小,但 V8 的优化器使用函数中人类可读代码的长度,包括注释。
因此,如果你在一个函数中放置太多注释,它可能会超过 V8 的任意内联函数长度阈值,突然你又要付出函数调用的开销了。
请查看 Julien Crouzet 的简洁帖子了解更多详细信息:
请注意,朱利安谈论的是曲轴;此后,V8 引入了 TurboFan,但源长度标准仍然存在。
完整的标准列表位于(非常可读的)TurboFan 源代码中,其中突出显示了源长度标准: