今天看啥  ›  专栏  ›  zidea

提升 javascript 代码性能

zidea  · 简书  ·  · 2019-01-16 06:02

文章预览

今天我们通过分析在 V8 引擎中是如何提升我们代码的性能的。今天先谈常见的元素种类

运行 JavaScript 代码时,V8 会跟踪每个数组所包含的元素。这些信息可以帮助 V8 优化数组元素的操作。例如,当您在数组上调用 reduce,map 或 forEach 时,V8 可以根据数组包含哪些元素来优化这些操作。

在 JavaScript 代码中,创建一个由数字类型的值组成的数组,当您在数组上调用 reduce,map 或 forEach 时,V8 可以根据数组包含哪些元素来优化这些操作。


在 JavaScript 我们可以为数组添加任意的数据类型的元素。就这个数组来说,如果你使用 typeof 操作符检查每个元素的类型,javascript 会告诉你数组包含都是 numbers。在语言层面,JavaScript 不区分整数,浮点数和双精度 - 只是数字。然而,在引擎级别,可以做出更精确的区分。


这个数组的元素是 PACKED_SMI_ELEMENTS。在 V8中,术语 Smi 是指用于存储小整数的特定格式。(后面我们会在 PACKED 部分中说明。)

如果我们添加 4.56 到数组。

这时我们的元素的类型就需要升级为 PACKED DOUBLE ELEMENTS 请注意,双精度浮点数是 Smi 的更为一般的变体,而常规元素是双精度浮点数之上的另一个概括。可以表示为 Smi 的数字集合是可以表示为 double 的数字的子集。

我们继续向数组添加新的元素,这次是字符串 x 。元素类型也升级到 PACKED ELEMENT

值得注意的是,元素种类转换只能从一个方向进行:从特定的(如 PACKED_SMI_ELEMENTS)到更一般的(例如 PACKED_ELEMENTS)。例如,一旦数组被标记为 PACKED_ELEMENTS,元素就不能回到 PACKED_DOUBLE_ELEMENTS。

我们表格形式表示上面我们创建的长度为 5 的数组。

如果我们现在跳过一些位置,对数组索引为 9 位置为 10 的进行赋值,那么就在 5 - 8 位置上留下空位。

因为这些空位存在我们的元素类型就变为了 HOLEY_ELEMENTS。

在计算过程中可能我们需要获取索引为 8 位子上的数值。

1. 首先检查数组的索引是否大于 0 并且确保该索引没有溢出。

2. 调用该 array 的 hasOwnProperty 来检查是否存储值为 8 的属性值。

3. 如果在该 array 上无法找到属性为 8 的值,我们都知道 javascript 是靠原型链来实现继承的,所以会继续向上查找 Array.property 是否具有该属性。

我们继续向上追溯,因为 Array是源于也就是继承于 Object 所以检查 Object.prototype 是否与8 的属性。

最后我们顺着原型链向上查找,发现没有属性 8 对应的值,得出结论在 80 位置上没有值 undefined。对于有空位置这样稀疏数值,检验是否存在的成本是高价的。我们再看检查密集(packedArray) 这样没有空位置数据是我们无需过多的步骤就可以判断是否存在值。


所以我们在开发时要避免有空位置的稀疏数组,取而代之尽量使用没有空位置的密集数组。

………………………………

原文地址:访问原文地址
快照地址: 访问文章快照
总结与预览地址:访问总结与预览