今天我们通过分析在 V8 引擎中是如何提升我们代码的性能的。今天先谈常见的元素种类
![](https://img.haomeiwen.com/i8207483/2174e1f89f8f2db8.jpg)
运行 JavaScript 代码时,V8 会跟踪每个数组所包含的元素。这些信息可以帮助 V8 优化数组元素的操作。例如,当您在数组上调用 reduce,map 或 forEach 时,V8 可以根据数组包含哪些元素来优化这些操作。
在 JavaScript 代码中,创建一个由数字类型的值组成的数组,当您在数组上调用 reduce,map 或 forEach 时,V8 可以根据数组包含哪些元素来优化这些操作。
在 JavaScript 我们可以为数组添加任意的数据类型的元素。就这个数组来说,如果你使用 typeof 操作符检查每个元素的类型,javascript 会告诉你数组包含都是 numbers。在语言层面,JavaScript 不区分整数,浮点数和双精度 - 只是数字。然而,在引擎级别,可以做出更精确的区分。
![](https://img.haomeiwen.com/i8207483/3228e3d456e650ae.jpg)
这个数组的元素是 PACKED_SMI_ELEMENTS。在 V8中,术语 Smi 是指用于存储小整数的特定格式。(后面我们会在 PACKED 部分中说明。)
![](https://img.haomeiwen.com/i8207483/8c1df9e64bb3d545.jpg)
如果我们添加 4.56 到数组。
![](https://img.haomeiwen.com/i8207483/7b66644395e9c565.jpg)
这时我们的元素的类型就需要升级为 PACKED DOUBLE ELEMENTS 请注意,双精度浮点数是 Smi 的更为一般的变体,而常规元素是双精度浮点数之上的另一个概括。可以表示为 Smi 的数字集合是可以表示为 double 的数字的子集。
![](https://img.haomeiwen.com/i8207483/7d8c30a40128b2cb.jpg)
我们继续向数组添加新的元素,这次是字符串 x 。元素类型也升级到 PACKED ELEMENT
![](https://img.haomeiwen.com/i8207483/60c20cc2ab9e537d.jpg)
值得注意的是,元素种类转换只能从一个方向进行:从特定的(如 PACKED_SMI_ELEMENTS)到更一般的(例如 PACKED_ELEMENTS)。例如,一旦数组被标记为 PACKED_ELEMENTS,元素就不能回到 PACKED_DOUBLE_ELEMENTS。
![](https://img.haomeiwen.com/i8207483/9f3b257217f89d57.jpg)
我们表格形式表示上面我们创建的长度为 5 的数组。
![](https://img.haomeiwen.com/i8207483/d0d60af9b4c73fad.jpg)
如果我们现在跳过一些位置,对数组索引为 9 位置为 10 的进行赋值,那么就在 5 - 8 位置上留下空位。
![](https://img.haomeiwen.com/i8207483/a785f500e98ccd26.jpg)
因为这些空位存在我们的元素类型就变为了 HOLEY_ELEMENTS。
![](https://img.haomeiwen.com/i8207483/4e286464583bf236.jpg)
在计算过程中可能我们需要获取索引为 8 位子上的数值。
![](https://img.haomeiwen.com/i8207483/d1b1bc310ec809ed.jpg)
1. 首先检查数组的索引是否大于 0 并且确保该索引没有溢出。
![](https://img.haomeiwen.com/i8207483/b934597a17200442.jpg)
2. 调用该 array 的 hasOwnProperty 来检查是否存储值为 8 的属性值。
![](https://img.haomeiwen.com/i8207483/1217a7492252c68b.jpg)
3. 如果在该 array 上无法找到属性为 8 的值,我们都知道 javascript 是靠原型链来实现继承的,所以会继续向上查找 Array.property 是否具有该属性。
![](https://img.haomeiwen.com/i8207483/611fe1f3de055ac4.jpg)
我们继续向上追溯,因为 Array是源于也就是继承于 Object 所以检查 Object.prototype 是否与8 的属性。
![](https://img.haomeiwen.com/i8207483/aa6ff7c19d465e24.jpg)
![](https://img.haomeiwen.com/i8207483/9721ec8b6193bf7f.jpg)
最后我们顺着原型链向上查找,发现没有属性 8 对应的值,得出结论在 80 位置上没有值 undefined。对于有空位置这样稀疏数值,检验是否存在的成本是高价的。我们再看检查密集(packedArray) 这样没有空位置数据是我们无需过多的步骤就可以判断是否存在值。
![](https://img.haomeiwen.com/i8207483/4cf5f4ef8a7ed814.jpg)
![](https://img.haomeiwen.com/i8207483/16e47b81d9e51821.jpg)
所以我们在开发时要避免有空位置的稀疏数组,取而代之尽量使用没有空位置的密集数组。
![](https://img.haomeiwen.com/i8207483/e48d5e9b6e08ef93.jpg)
网友评论