【问题标题】:Is there a more run-time efficient way to iterate through this array? (JavaScript)是否有更高效的方式来遍历这个数组? (JavaScript)
【发布时间】:2020-01-05 16:30:46
【问题描述】:

所以我只是想知道在下面这个简单的函数中为变量赋值是否会降低运行时效率:

const biggestNumberInArray = (arr) => {
  let biggest = 0;
  for (item of arr) {
    biggest = (item > biggest) ? item : biggest;
  }
  return biggest;
}

在 for 循环中,每次迭代都会为变量 biggest 赋值。所以如果我改写:

if (biggest < item) { biggest=item;};

这个功能会变得更有效率吗?我真的没有什么大数组,这个问题主要是理论上的,我想了解力学是如何工作的。

谢谢!

【问题讨论】:

  • Math.max 会更高效
  • 这项作业只需要很短的时间。除非您实际上已经对其进行了基准测试并且有理由怀疑它可能会更快,否则请选择更好的选择。
  • 运行一次数组是 N。比较每个是 N。在每次迭代中分配是 N。所以你有最多 3N 次操作和最少 2N+1...这是一个很好的折衷方案,我看不出你的代码有什么问题。

标签: javascript arrays performance memory-efficient


【解决方案1】:

考虑两种观点:

  1. 理论的角度来看,即考虑到渐近复杂度,它没有任何区别。两种算法都将在线性时间 - O(n) 上运行,因为无论如何您都必须遍历数组。作业需要固定的时间。 if 子句也需要固定时间。一个常数时间或两个常数时间仍然是常数时间。

  2. 实用的角度来看,它可能会有所不同,但可能并不相关,尤其是对于大型阵列。对于小数组,相对差异可能更相关,但由于时间少,我们通常不会太在意。

【讨论】:

    【解决方案2】:

    我在jsbench.me 上对以下 5 个函数进行了基准测试(链接转到保存的测试):

    const data = [1,2,3,4,5,6,7,8,9,0,99,88,77,66,55,44,33,22,11]
    
    const fn1 = xs => xs.reduce((acc, x) => acc > x ? acc : x, -Infinity)
    
    const fn2 = xs => {
      let res = -Infinity
      for (const x of xs) res = x > res ? x : res
      return res
    }
    
    const fn3 = xs => {
      let res = -Infinity
      for (const x of xs) {
        if (x > res) res = x
      }
      return res
    }
    
    const fn4 = xs => xs.reduce((acc, x) => Math.max(acc, x), -Infinity)
    
    const fn5 = ([x, ...xs], acc = -Infinity) =>
      x == undefined ? acc : fn5(xs, x > acc ? x : acc)
    

    到目前为止,最快的函数是 #1,基于 Array.prototype.reduce 并避免任何重新分配。

    功能 #2 - #4(包括您的原始功能和您建议的具有潜在性能改进的功能)都始终比 #1 慢 40-55%。 #4(reduceMath.max)似乎始终比 #2 和 #3 快 20% 左右。

    最慢的函数(取决于递归)是 #5,比 #1 慢大约 80-90%。

    Math.max(x, y)x &gt; y ? x : y 慢。

    我在运行 macOS 10.15.1 (Catalina) 和 Chrome v79.0.3945.88(64 位)的 2019 MacBook Pro 上进行了测试。使用不同的测试设置,您最终可能会得到不同的结果,但我有理由相信,基于 reduce 并避免重新分配的解决方案将是大多数现代浏览器中最快的选择。

    【讨论】:

    • 有趣。在我的安卓智能手机上,“减少 Math.max”始终是最快的。但使用“减少三元”仅慢 3.2%。 +1
    猜你喜欢
    • 2021-11-12
    • 1970-01-01
    • 2016-03-24
    • 2023-03-11
    • 1970-01-01
    • 1970-01-01
    • 2017-03-04
    • 1970-01-01
    • 2021-02-28
    相关资源
    最近更新 更多