【问题标题】:javascript concat vs push benchmarkjavascript concat vs push 基准测试
【发布时间】:2014-10-09 23:30:03
【问题描述】:

在 jsperf 上有这个测试: http://jsperf.com/javascript-array-concat-vs-push

这表明 concat 更快,但如果你在初始数组中得到该结果,而不使用第三个变量,concat 会慢得多:

for (i = 10000; i > 0; i--) {
   arr1 = arr1.concat(arr2);
}

即使你使用本地变量,但名称相同,结果也是一样的:

for (i = 10000; i > 0; i--) {
   var arr1 = arr1.concat(arr2);
}

谁能解释一下?

【问题讨论】:

  • 不确定我是否明白这个问题,concatpush 做不同的事情,一个连接两个数组,另一个推送到一个数组,但如果你对 apply 使用一些技巧,你可以使用一行代码而不是迭代将所有值从一个数组推送到另一个数组,但当然原生方法通常更快。
  • 首先,您正在显着更改初始性能测试的条件:每次迭代时附加的数组都更大。除此之外,如果您不使用第三个变量,则会在每次迭代时创建和销毁一个辅助变量,这将解释额外的性能下降。
  • 你的两个例子是等价的。 Javascript 变量具有函数作用域,而不是块作用域,因此变量声明被吊出循环。
  • @adeneo 如果您查看他链接到的 jsperf,它确实使用了“apply 的诡计”
  • 在我看来,jsperf 是在比较苹果和橙子。 concat 测试将结果放入一个新变量中,因此它只是多次连接相同的两个数组。 push 测试正在修改原始数组之一,因此它在测试的每次迭代中不断增长。您的concat 测试类似于基准测试中的push 测试,因为您将结果保存在arr1 中。这就是性能类似于push 基准的原因。

标签: javascript performance


【解决方案1】:

您正在循环中改变原始数组。

for (i = 10000; i > 0; i--) {
   arr1 = arr1.concat(arr2);
}

这里arr1 的大小不断增长,随着数组变大,它会变慢,因为它必须分配更多内存。

for (i = 10000; i > 0; i--) {
   var arr3 = arr1.concat(arr2);
}

在这里,您将分配给一个新变量而不改变 arr1arr2,因此您可以测试连接两个小数组的性能。

arr1 案例中,您测试了将一个大数组与一个小数组连接起来的性能。

【讨论】:

  • 你没有抓住重点。问题是关于 concat 与 push
  • 可能比这更阴险。因为 arr3 没有在其他任何地方使用,所以优化器很有可能已经决定“嘿,为什么还要 concat?无论如何该值都被丢弃了,所以假设我们这样做并提前终止”。
  • 没有@ovi,问题的标题可能是“concat 与 push”,但实际问题是“有人可以解释一下吗?”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-24
  • 2020-07-04
  • 1970-01-01
  • 1970-01-01
  • 2011-11-27
  • 2014-04-24
相关资源
最近更新 更多