【问题标题】:What are the performance concerns of chaining multiple Array.prototype.*function*?链接多个 Array.prototype.*function* 的性能问题是什么?
【发布时间】:2018-08-12 16:22:10
【问题描述】:

假设我有一个函数 f,它遍历 n 元素的数组以使用 k 条件对其进行过滤。

为了提高可读性,我很想这样写:

result = array
    .filter(predicate1)
    .filter(predicate2)
    .filter(predicate3)
    .filter(...)

尤其是为了避免这样写:

result = array.filter(e => test1(e) && test2(e) && test3(e) && ...)

当然,上面看起来还不错,但是如果我有多个测试很难写好并且最终会变成一堆缩进......(请考虑一下)

拥有k 数量的谓词。复杂度好像是O(k*n)吧?

如果出现以下情况,会有哪些性能风险:

  • 数组中有很多元素(假设的很多,我真的很感谢您对很多的定义)
  • 我们每秒执行几次函数f,甚至更多次
  • 也可以执行其他类似的功能

我已经采用了过滤器的情况,因为我刚刚遇到它,但这个问题适用于迭代数组或其他可迭代对象时使用的任何链式方法。

编辑:

其实我真正想知道的是在全球范围内使用这种设计的危险性。

当然,对于单个函数来说,这不会是一个太大的问题。我说的是对完整应用程序的影响,其中每个类似的案例都会使用更多的迭代。

【问题讨论】:

  • 正如你所说,多次运行数组O(k*n) 超过O(n) 是不好的,而且你建议的替代方案没有副作用,看起来也不错,所以只需使用它。
  • 唯一能小幅提升性能的是数组可以在每次迭代时变小。
  • 反复使用过滤器会反复创建对性能不利的数组
  • @SebastianSpeitel - 这不会比&& 版本提高性能。

标签: javascript arrays iteration time-complexity


【解决方案1】:

性能风险只是重复迭代(和/或创建然后回收这些临时数组)而不是单次迭代所花费的时间会在您的应用程序中产生可察觉的延迟,可能仅在功能较低的硬件上.一般建议是:编写清晰且可维护的内容,并在/当您担心性能问题时担心性能问题。

从您问题中的信息中无法判断您是否会得到一个。您已经说过数组中有“很多”条目,但“很多”并不能告诉我们太多。 :-) 您还说过您将每秒执行几次此处理,这确实表明您最好不要不必要地循环遍历数组并创建中间数组。但您的里程可能会有所不同。

如果您经常遇到这种情况,您可以考虑给自己一些实用功能,例如:

function multiAndFilter(array, ...filters) {
    return array.filter(entry => filters.every(entry));
}
function multiOrFilter(array, ...filters) {
    return array.filter(entry => filters.some(entry));
}

...等等,然后:

result = multiAndFilter(array, predicate1, predicate2, predicate3);

【讨论】:

    【解决方案2】:

    您可以通过为谓词函数获取一个数组并对其进行迭代来保持可读性和可维护性。

    然后采取一个单循环进行拟合。

    predicates = [test1, test2, test3];
    result = array.filter(e => predicates.every(fn => fn(e)));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-09-14
      • 2011-06-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-19
      • 2018-10-30
      • 1970-01-01
      相关资源
      最近更新 更多