【问题标题】:performance - foreach with condition inside vs filter with same condition and foreach on filtered array in javascript性能 - 带有条件的 foreach 与具有相同条件的过滤器和 foreach 在 javascript 中的过滤数组上
【发布时间】:2021-07-02 14:31:41
【问题描述】:

我有一个关于性能的问题。 假设我有大量名为records 的对象。 我的目标是创建一个集合(确保我有不同的值),其中包含来自records 的记录的值value 满足一定条件 - if(rec.otherValue === 'something specific')。 我有两种可能的方法可以产生预期的结果:

选项 1:

const set = new Set();
records.foreach(rec => {
   if(rec.otherValue === 'something specific'){
       set.add(rec.value);
   }
});

第一个选项是直截了当的。如果满足特定条件,我会遍历所有记录并将所需的值添加到 Set。

选项 2:

const set = new Set();
const filteredRecords = records.filter(rec => rec.otherValue === 'something specific');
filteredRecords.foreach(rec => {
   set.add(rec.value);
});

第二个选项首先过滤大量 records 数组以获得更具体的对象数组(从数百条记录到少于 10 条),然后将所需的值添加到 Set。

这两个选项产生完全相同的结果。 我的问题是:哪一个是性能最好的?我的目标是使功能尽可能快。 如果还有第三种更快的选择,请分享。

【问题讨论】:

  • 您听说过大 O 符号吗?在您的情况下,复杂性始终为 O(n)。而且性能是一样的。第一种方法使其更具可读性:) 请在此处查看stackoverflow.com/questions/16917958/…
  • @hurricane 是的,我很清楚 O 表示法,我也知道它会给我 O(n) 的时间复杂度。但我的问题不是关于时间复杂度——而是关于性能。我敢肯定 js 的开发者在性能方面以最好的方式开发了这两个功能。这并不意味着尽管它们具有相同的时间复杂度,但它们都具有相同的速度/性能/资源分配
  • Which one is the best performance-wise? 它们是等价的,因为它们具有相同的时间复杂度。差异将以纳秒为单位。

标签: javascript arrays performance


【解决方案1】:

那么这个呢?我认为它具有很高的可读性,这比性能更重要。

const condition = val => val === 'something specific'
const set = new Set(records.filter(condition))

【讨论】:

    【解决方案2】:

    如果您想要速度,就性能而言,没有什么能比原生(香草)javascript 更好。 那么,

    for (var i=0; i< records.length; i++) {
    // your operations
    }
    

    请查看:Why using for is faster than some() or filter()

    https://web.archive.org/web/20170403221045/https://blogs.oracle.com/greimer/entry/best_way_to_code_a

    【讨论】:

      【解决方案3】:

      对此进行测试
      我很好奇现代方法的速度有多快,所以我在 JSPerf 上设置了一些测试。这是我发现的:

      • for 循环和 forEach() 方法的性能非常接近。
      • map()filter() 等方法的速度大约是使用 forEach() 并推送到新数组以执行相同操作的速度的两倍。
      • 使用forEach() 进行多步操作的速度大约是filter()map() 等链接方法的两倍。
      • 这些结果在 Chrome、Firefox 和 Safari 中是一致的。我担心只有 V8 JavaScript 渲染引擎以这种方式进行了优化,但所有现代浏览器都看到了类似的结果。

      Link to source
      Benchmark for: reduce(), filter(), map(), forloop and forEach()

      我尝试多次运行基准测试,结果 for 循环是最慢的,而 forEach()reduce() 是最快的。

      您可以使用另一个选项,使用reduce()

      这是一个例子:

      let data = [
        {
          id: 1,
          value: 'one'
        }, {
          id: 2,
          value: 'two'
        }, {
          id: 3,
          value: 'three'
        }, {
          id: 4,
          value: 'four'
        }, {
          id: 5,
          value: 'five'
        },
      ];
      
      // Filters IDs of odd numbers [1,3,5]
      let new_arr = data.reduce((a, b) => {
        if ([1,3,5].includes(b.id)) {
          a.push(b.value);
        }
        return a;
      }, []);
      console.log(new_arr); // Expected Result: ['one', 'three', 'five']
      
      // Or you can use this one Liner
      let new_arr_1 = data.reduce((a, b) => a.concat(([1,3,5].includes(b.id) ? b.value: [])), []);
      console.log(new_arr_1); // Expected Result: ['one', 'three', 'five']

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-03-02
        • 1970-01-01
        • 1970-01-01
        • 2021-04-08
        • 2023-03-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多