那么,另一个优化问题。我想知道V8 是否对变量进行类型推断,然后根据该变量优化访问。
类型推断将是这样的:
let input = "keyboard";
// ^^^^^ input is String because "keyboard" is String
V8上是否存在可能无法推断类型并且意外未对其进行优化的情况,例如,因为某些表达式的类型只能在运行时获得?
将zxc
置于本地s
let s = ''; // let s : String
s = zxc; // What is zxc?
替代
let s = '';
s = zxc + '';
答案 0 :(得分:1)
是的,绝对。
例如,从2012年开始,V8标签为32位数字,因此每次计算都要快得多。证明https://www.html5rocks.com/en/tutorials/speed/v8/#toc-topic-numbers
Crankshaft在各处引入混合型推理,以加快未改变类型的每个字段访问。
Current Ignition做得越来越好,当然还是使用字段类型的知识来构建本机代码路径。
当有人将无法预测的类型的值写入已知字段时,它有自己的去优化价格。
答案 1 :(得分:1)
(V8开发人员在这里。)简短的回答是“是和否”。答案很长很复杂。
let s = '';
示例中没有直接的“变量类型推断” - 正是因为下一个分配可能是s = 1
。
也就是说,现代JavaScript引擎(V8和其他)生成优化代码的基本原则之一是通过观察在程序中的特定点看到的类型。例如,当您有... = s + t
时,到目前为止s
和t
一直是字符串,那么优化代码将包含大致类似的序列:
check if the value in s is a string, otherwise bail out;
check if the value in s is a string, otherwise bail out;
perform a string concatenation of the two values;
其中“bail out”意味着抛弃整个函数的优化代码,并继续执行未经优化的代码(或字节码),这不会对类型产生假设。基于关于类型的更新信息,可以稍后生成或不生成新的优化代码。这种方法不是通常所谓的“类型推断”。
JavaScript中的直接“类型推断”只能在非常有限的情况下使用。例如,按位运算的结果(如|
,&
,
~
)始终是32位整数;一元加的结果(即+foo
)总是一个数字;将字符串添加到其他任何内容的结果始终是字符串。优化编译器通常会应用此类规则来生成更高效的代码。