简体   繁体   English

有没有更高效的方法来迭代这个数组? (JavaScript)

[英]Is there a more run-time efficient way to iterate through this array? (JavaScript)

So I'm just wondering whether assigning value to a variable takes away from the run-time efficiency in this simple function below:所以我只是想知道在下面这个简单的函数中为变量赋值是否会降低运行时的效率:

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

Inside the for loop, every iteration is, well, assigning a value to the variable biggest .在 for 循环中,每次迭代都是为变量maximum赋值。 So if I would write instead:所以如果我改写:

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

would the function become more efficient?该功能会变得更有效率吗? I don't really have any big array, this question is mostly theoretical, I wanna understand how to mechanics work.我真的没有任何大数组,这个问题主要是理论性的,我想了解机制是如何工作的。

thank you!谢谢你!

Considering two points of view:考虑两个观点:

  1. From a theoretical point of view, ie, considering the Asymptotic Complexity , it does not make any difference.理论的角度来看,即考虑Asymptotic Complexity ,它没有任何区别。 Both algorithms would run on linear time - O(n), since you have to iterate over the array anyway.两种算法都将在线性时间上运行 - O(n),因为无论如何您都必须遍历数组。 Assignments take constant time.作业需要固定的时间。 The if clause also takes constant time. if 子句也需要恒定的时间。 One constant time or two constant time is still constant time.一个恒定时间或两个恒定时间仍然是恒定时间。

  2. From a practical point of view, it may make some difference, but it probably wouldn't be relevant, especially for big arrays.实际的角度来看,它可能会有所不同,但它可能不相关,尤其是对于大数组。 For small arrays, the relative difference may be more relevant, but since the time is low, we usually don't care much about it.对于小数组,相对差异可能更相关,但由于时间较短,我们通常不会太在意。

I benchmarked the following 5 functions on jsbench.me (link goes to saved tests):我在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)

The fastest function, by far, is #1, based on Array.prototype.reduce and avoiding any reassignment.到目前为止,最快的函数是#1,基于Array.prototype.reduce并避免任何重新分配。

Functions #2 - #4 (including your original function and one with the potential perf improvement you suggested) are all consistently between 40-55% slower than #1.功能 #2 - #4(包括您的原始功能和您建议的具有潜在性能改进的功能)都始终比 #1 慢 40-55%。 #4 ( reduce with Math.max ) seems to be consistently faster than #2 and #3 by around 20%. #4(用Math.max reduce )似乎始终比 #2 和 #3 快 20% 左右。

The slowest function (which depends on recursion) is #5, clocking in at around 80-90% slower than #1.最慢的函数(取决于递归)是 #5,比 #1 慢 80-90%。

Math.max(x, y) is slower than x > y ? x : y Math.max(x, y)x > y ? x : yx > y ? x : y x > y ? x : y . x > y ? x : y

I tested on a 2019 MacBook Pro running macOS 10.15.1 (Catalina) and Chrome v79.0.3945.88 (64bit).我在运行 macOS 10.15.1(Catalina)和 Chrome v79.0.3945.88(64 位)的 2019 款 MacBook Pro 上进行了测试。 You may end up with different results with a different test setup, but I'm reasonably confident that a solution based on reduce and avoiding reassignment will be the fastest option in most modern browsers.使用不同的测试设置最终可能会得到不同的结果,但我有理由相信基于reduce和避免重新分配的解决方案将是大多数现代浏览器中最快的选择。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM