V8 是否能够根据“const”的值消除死代码?

Can*_*ure 5 javascript performance v8 dead-code code-elimination

假设 V8 将完全消除死代码(结构如下)是否正确?

文件module1.js

export const DEBUG = false
Run Code Online (Sandbox Code Playgroud)

文件module2.js

import { DEBUG } from './module1.js'

if (DEBUG) {
    // dead code eliminated?
}
Run Code Online (Sandbox Code Playgroud)

请不要评论“‘if’检查的开销非常小,你应该 XXX 而不是问这个问题”。我只是想知道 V8 是否能够做到这一点(是/否,当然最好有一些细节)。

jmr*_*mrk 10

V8 开发者在这里。答案通常是“视情况而定”。

V8 的优化编译器支持死代码消除,因此,是的,在适当的情况下,永远无法采用的条件分支将被消除。

也就是说,在您发布的具体示例中,顶级代码不会得到优化(可能 - 取决于其中的其他内容),因此在这种情况下不会,检查if (DEBUG)将被编译(到未优化的字节码)并且执行——一次,因为执行一次比第一次尝试优化(并可能消除)它要快得多。

另一件需要考虑的事情是,V8 会“延迟”编译函数,即按需编译。这意味着,如果您有一个永远不会被调用的整个函数(例如,因为它唯一的调用站点位于if (DEBUG)-block 和DEBUGis中false),那么该函数甚至不会被编译为字节码,更不用说优化代码了。这并不是传统意义上的死代码消除,但可以说它更好:-)

总之:如果您的应用程序中散布了一些DEBUG代码,那么将其保留在里面是完全可以的。要么它位于很少执行的路径中,在这种情况下,执行检查的成本并不重要;要么它位于很少执行的路径中,在这种情况下,执行检查的成本并不重要;或者它会处于热路径中,在这种情况下,V8 将对其进行优化并消除条件。但是,如果您有大量此类代码,那么删除它有两个优点:下载大小和解析时间。当 JavaScript 代码到达浏览器时,引擎别无选择,只能至少简单地查看它的每个字节(如果只是为了弄清楚有哪些函数,以及代码的哪些部分位于顶层并且必须立即执行),字节越少,该步骤完成的速度就越快。解析速度很快,但解析一半甚至更快!