【问题标题】:How to best optimize a function with a nested for-loop如何使用嵌套的 for 循环最好地优化函数
【发布时间】:2017-11-11 22:12:45
【问题描述】:

我有一个function,它有一个嵌套的for loop。随着function 迭代更多数据,它开始变慢。我怎样才能最好地优化这个功能,使它运行得更快一点?

function rubicoGVB(arr, range) {
    var res = [];
    for (var i = 0; i < arr.length; i++) {
        for (var j = i + 1; j < arr.length; j++) {
            if ((arr[i] + arr[j]) / range < 16487665) {
                res.push(arr[i]);
            }
        }
    }

    return res.length;
}

【问题讨论】:

  • 也许更适合codereview.stackexchange.com
  • 如果你只想返回长度你不需要 res 数组
  • @reski:根据您在上面使用let 的方式,它要么没有任何区别,要么会减慢速度。它不会加快速度。
  • 你能告诉我们更多关于函数应该计算什么,以及它的输入是什么样子的(例如range总是一个正整数)吗?如果您的数据已排序,您可以显着加快计数速度 - 达到可能值得对其进行排序的程度
  • jsperf.com/array-range-count/1 创建了一个性能。

标签: javascript memory optimization


【解决方案1】:

(Fast Snail in this comment 描述了您可以做出的最大改进:您不需要 res 数组来返回其长度;只需使用计数器即可。以下是您可以做出的其他改进。)


看看这些循环,除了:

  1. 缓存数组的长度,以及

  2. 缓存arr[i],而不是在j循环中重复查找

...这是最小的(但真正的)改进,请参阅下面的 lenentry

function rubicoGVB(arr, range) {
    var res = [];
    var len = arr.length;
    var entry;
    for (var i = 0; i < len; i++) {
        entry = arr[i];
        for (var j = i + 1; j < len; j++) {
            if ((entry + arr[j]) / range < 16487665) {
                res.push(entry);
            }
        }
    }

    return res.length;
}

【讨论】:

  • 不要每次都计算除法
  • @Bergi:根据我们目前掌握的信息,我们将如何(合理地)避免这种情况?
  • 循环外的var max = 16487665 * rangeentry + arr[j] &lt; max
  • @T.J.Crowder 可能entry + arr[j] 相当大,而range 相当小,否则谓词一开始就没有多大意义。如果冒险进入浮点不准确的领域将是一个问题,那么当前代码也可能存在问题。
  • @T.J.Crowder 感谢您的帮助。我从你的建议中学到了很多。我现在看到你我不需要res 数组,我可以简单地return 一个计数器来代替。
猜你喜欢
  • 1970-01-01
  • 2012-01-27
  • 2020-05-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-26
相关资源
最近更新 更多