V8元素种类优化

V8 elements kinds optimization

阅读这篇文章后:https://v8.dev/blog/elements-kinds,我想知道 nullobject 在内部优化方面是否被 V8 认为是同一类型。

例如
[{}, null, {}] 对比 [{}, {}, {}]

是的。考虑元素种类的唯一类型是 "small integer"、"double" 和 "anything"。 null 不是整数或双精度数,所以它是 "anything"。

请注意,元素种类是按数组而不是按元素跟踪的。数组的元素种类是其任何元素所需的最通用的元素种类:

[1, 2, 3]     // "integer" elements (stored as integers internally)
[1, 2, 3.5]   // "double" elements (stored as doubles: [1.0, 2.0, 3.5])
[1, 2, {}]    // "anything" elements
[1, 2, null]  // "anything" elements
[1, 2, "3"]   // "anything" elements

原因在于,首先跟踪元素种类的好处是可以避免一些检查。这对原本成本低廉的运营产生了重大影响(相对而言)。例如,如果你想对一个数组的元素求和,这些元素都是整数:

for (let i = 0; i < array.length; i++) result += array[i];

整数相加真的很快(一条指令+溢出检查),所以检查每个元素"is this element an integer (so I can do an integer addition)?"(另一条指令+条件跳转)增加了相对较大的开销,所以预先知道这个数组中的每个元素都是一个整数 让引擎跳过循环内的那些检查。而如果数组包含字符串并且您想将它们全部连接起来,则字符串连接是一个慢得多的操作(您必须为结果分配一个新的字符串对象,然后决定是要复制字符还是只引用输入strings),因此额外的 "is this element a string (so I can do a string concatenation)?" 检查所增加的开销可能几乎无法衡量。因此,将 "strings" 作为一种元素进行跟踪不会带来太多好处,但会增加实现的复杂性,并且在某些情况下可能会降低性能,因此 V8 不会这样做。类似地,如果您预先知道 "this array contains only null",那么没有什么明显可以加快您掌握这些知识的速度。

此外:作为 JavaScript 开发人员,不必担心元素种类。将该博客 post 视为一个(希望有趣的)故事,讲述 V8 竭尽全力从您的代码中榨取每一点性能;不要专门扭曲您的代码以更好地利用它(或花时间担心它)。差异通常很小,在重要的情况下,它可能会在您无需考虑的情况下发生。