Javascript 为什么新阵列速度慢?

Javascript 为什么新阵列速度慢?,javascript,arrays,benchmarking,profile,Javascript,Arrays,Benchmarking,Profile,在比较操作时 var fat_cats = cats.slice() 到 性能差异令人困惑 在firefox和chrome中,新数组的速度较慢(当它应该更快时,它只是分配一个空数组,而不是在上面进行迭代) 其中,与IE8中的一样,新阵列的速度更快(这让人困惑) 任何解释都将不胜感激 通过查看V8的阵列函数,找到了答案 如果一个数组有1000多个元素,并且调用了.slice,则会使用名为SmartSlice的函数,而不是其他情况下使用的SimpleSlice函数 SimpleSlice实现为fo

在比较操作时

var fat_cats = cats.slice()

性能差异令人困惑

在firefox和chrome中,新数组的速度较慢(当它应该更快时,它只是分配一个空数组,而不是在上面进行迭代)

其中,与IE8中的一样,新阵列的速度更快(这让人困惑)

任何解释都将不胜感激


通过查看V8的阵列函数,找到了答案

如果一个数组有1000多个元素,并且调用了
.slice
,则会使用名为
SmartSlice
的函数,而不是其他情况下使用的
SimpleSlice
函数

SimpleSlice
实现为for循环副本(与数组副本测试用例中的代码完全相同)<另一方面,code>SmartSlice使用稀疏数组来表示数据

在元素数量从10000个降至1000个以下的情况下,它们的性能完全相同(在误差范围内),而在变化较少且元素数量超过1000个的情况下,SmartSlice方法比原始拷贝快约36%


虽然这完美地解释了V8方面的问题,但我不知道为什么Firefox在新阵列上的速度也比切片阵列慢,即使在更小的尺寸上也是如此——除非它们有类似的优化(可能适用于所有切片函数)

编辑


这一直困扰着我,所以我下载了Firefox源代码并签出了
js/src/jsarray.cpp!数组_slice
,Firefox也有类似的优化:slice的结果是一个
DenseCopiedArray
DenseAllocatedArray
,这显然类似于V8稀疏数组。

@MahmoudAl Qudsi无论哪种方式,用这些值覆盖数组我都不认为测试用例有效,当您介绍一些缓存局部性问题时。我认为你应该坚持
j[I]=a[I]/255始终,而不是在它和
j[i]=j[i]/255之间切换,由于缓存位置的原因,这可能(自然)更快。编辑-将测试用例更改为更有效,结果仍然相同:在“克隆空循环”基准测试中,您有
var j=new Array(a.Length)
而不是
a.Length
,因此
j
得到
var j=new Array(未定义)
。如果你解决了这个问题,它仍然会变慢,但幅度要小得多。在V8源代码中,它似乎是对大型阵列的优化。更新了我的答案。
.slice()
用于复制数组,因此它将创建一个新数组。不,这是我的观点。我认为它在第一次写入之前不会创建新数组,所以在那之前它们只是同一对象的别名?很好地处理了全局变量:)令人惊讶的是,这会产生如此大的差异。@RobW我不认为这是COW,实际上,我正在做更多的测试。但是你的写作并没有什么不同,因为它们都是在写作之后。它必须在切片之后和其他任何事情之前完成。@Rob W:你的观点是什么?无论如何,到那时整个阵列都将被复制。
var fat_cats = new Array(cats.length)