据我所知,V8的Javascript引擎会进行双数转换(到i32再回到i32)来执行位操作。
const int32 = new Int32Array(2);
int32[0] = 42;
int32[1] = 2;
const y = int32[0] | int32[1];
如果没有,是否意味着Int32Array值的位操作更快?
更新双重转换是指:从64位(53位精度)到->;32位,再到->;64位。
V8开发者在这里。简单的回答是:这里没有转换,位运算总是在32位整数上进行,而且一个 Int32Array
也将其元素存储为32位整数。
较长的答案是 "这取决于"。在未优化的代码中,所有的数值都使用统一的表示方式。在V8中,这意味着数字值如果在范围内(包括符号在内的31位,即大约-10亿到+10亿),要么用 "Smi"("小整数")表示,否则用 "HeapNumbers"(64位双数,有一个小对象头)表示。所以对于一个元素的加载,如 int32[0]
从数组中加载32位的值,检查其范围,然后将其标记为Smi或装箱为HeapNumber。下面是 |
操作查看输入,并将其转换为32位整数(可以是简单的解挂Smi,也可以是复杂的调用 .valueOf
对象上),并执行位上的 "或"。然后,结果再次被标记为Smi或框定为HeapNumber,这样下一个操作就可以决定如何处理它。
如果函数运行的频率足够高,最终得到优化,那么优化编译器就会利用类型反馈(必要时用类型检查来防范)来省略所有这些在这种情况下不必要的转换,简单的答案就会是真的。