为了账号安全,请及时绑定邮箱和手机立即绑定

读取数组的`length`属性真的在JavaScript中花费那么大的代价吗?

读取数组的`length`属性真的在JavaScript中花费那么大的代价吗?

智慧大石 2019-11-30 10:21:19
我一直认为在JavaScript中缓存数组的长度是一个好主意(尤其是在for循环的情况下),因为计算数组长度的开销很大。例for (var i = 0; i < arr.length; i++) { }// vsfor (var i = 0, arrLength = arr.length; i < arrLength; i++) { }但是,我认为也许length只有在创建和更改数组时才更新该属性。因此,与读取存储在变量中的操作相比,读取它的操作不会太昂贵(与其他语言的其他方法相对,后者可能需要在内存中寻找内容的结尾,例如strlen()在C语言中)。我有两个问题。我也对它的工作方式感兴趣,所以请不要用过早的优化工具打我。假设浏览器中的JavaScript引擎。length在JavaScript中缓存数组的属性有什么好处吗?在读取对象属性的局部变量时还有更多的事情吗?该length属性是否仅在创建时以及在on shift()和pop()type方法上进行了更改,这些方法不返回新数组,否则仅存储为整数?
查看完整描述

3 回答

?
饮歌长啸

TA贡献1951条经验 获得超3个赞

据我所知,似乎数组的长度是在内部缓存的(至少在V8中)。


(详细信息?请继续阅读:))


因此,这个问题在我的脑海中浮现了好几次,我已经决定找出问题的根源(至少在一个实现中)。


挖掘V8源代码会产生JSArray类。


// The JSArray describes JavaScript Arrays

//  Such an array can be in one of two modes:

//    - fast, backing storage is a FixedArray and length <= elements.length();

//       Please note: push and pop can be used to grow and shrink the array.

//    - slow, backing storage is a HashTable with numbers as keys.

我假设数组元素的类型决定了它是快还是慢。我到了set_has_fast_elements(set_bit_field2(bit_field2() | (1 << kHasFastElements)))中设置了一个位标志,这是我在Google代码中查找时要绘制挖掘线的地方,而本地没有源代码。


现在,它似乎是任何时候任何操作是在阵列上完成(这是一个子类的JSObject,就会调用作出NormalizeElements(),其执行以下操作:


// Compute the effective length.

  int length = IsJSArray() ?

      Smi::cast(JSArray::cast(this)->length())->value() :

      array->length();

因此,在回答您的问题时:


Chrome(或其他使用V8的浏览器)在缓存length数组的属性方面似乎没有任何优势(除非您做一些奇怪的事情将其强制为slow(我不确定这些条件是什么) )-话虽如此,我很可能会继续缓存,length直到有机会浏览所有 OS浏览器的实现;)

在对象上执行任何操作length后,该属性似乎已更改。

编辑:


附带说明,似乎“空”数组实际上已分配为具有4个元素:


// Number of element slots to pre-allocate for an empty array.

static const int kPreallocatedArrayElements = 4;

我不知道数组有多少元素增长由曾经的范围已经超出了-我没有挖的是深:)


查看完整回答
反对 回复 2019-11-30
?
慕妹3242003

TA贡献1824条经验 获得超6个赞

本文通过询问IRHydra生成的代码来研究V8和Chrome中的自动缓存:


Grinch如何通过Vyacheslav Egorov 窃取array.length


他发现在某些条件下,手动缓存.length实际上增加的开销而不是提高性能!


但是无论如何,这种微优化不可能为您的用户带来任何明显的收益。为了他们和您的利益,请专注于易于阅读的代码,并在代码中使用良好的数据结构和算法!


避免过早的优化:关注优美的代码,直到出现性能问题。只有这样,才能通过性能分析找出瓶颈,然后仅对代码的那部分进行优化。


查看完整回答
反对 回复 2019-11-30
  • 3 回答
  • 0 关注
  • 469 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信