v8 Javascript 引擎如何对 Int32Array 值执行位运算

cap*_*ian 2 javascript performance v8 bit-manipulation typedarray

据我所知,V8 Javascript 引擎会进行双数转换(到 i32 并返回)来执行位运算。让我们考虑下一个例子:

const int32 = new Int32Array(2);
int32[0] = 42;
int32[1] = 2;
const y = int32[0] | int32[1];
Run Code Online (Sandbox Code Playgroud)

在这种情况下,V8 会进行双重转换吗?如果不是,是否意味着 Int32Array 值上的位运算更快?

更新:通过双重转换,我的意思是:从 64 位(53 位精度)到 -> 32 位,然后再次到 -> 64 位

jmr*_*mrk 5

V8 开发者在这里。简短的回答是:这里没有转换,按位运算始终对 32 位整数执行,并且 anInt32Array还将其元素存储为 32 位整数。

更长的答案是“这取决于”。在未优化的代码中,所有值都使用统一的表示形式。在 V8 中,这意味着如果数值在范围内(包括符号在内的 31 位,即大约 -10 亿到 +10 亿),则数值要么表示为“Smi”(“小整数”),要么表示为“HeapNumbers”(64 -bit double 带有一个小对象头)否则。因此,对于像 之类的元素加载int32[0],将从数组加载 32 位值,检查范围,然后标记为 Smi 或装箱为 HeapNumber。以下|操作查看输入,将其转换为 32 位整数(可以像取消 Smi 标签一样简单,也可以像调用.valueOf对象一样复杂),然后执行按位“或”。然后,结果再次被标记为 Smi 或装箱为 HeapNumber,以便下一个操作可以决定如何处理它。

如果函数运行的频率足以最终得到优化,那么优化编译器会利用类型反馈(必要时由类型检查进行保护)来消除在这种情况下不必要的所有这些转换,并且简单的答案将是正确的。