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;
我不知道数组有多少元素增长由曾经的范围已经超出了-我没有挖的是深:)
TA贡献1824条经验 获得超6个赞
本文通过询问IRHydra生成的代码来研究V8和Chrome中的自动缓存:
Grinch如何通过Vyacheslav Egorov 窃取array.length
他发现在某些条件下,手动缓存.length实际上增加的开销而不是提高性能!
但是无论如何,这种微优化不可能为您的用户带来任何明显的收益。为了他们和您的利益,请专注于易于阅读的代码,并在代码中使用良好的数据结构和算法!
避免过早的优化:关注优美的代码,直到出现性能问题。只有这样,才能通过性能分析找出瓶颈,然后仅对代码的那部分进行优化。
添加回答
举报