繁体   English   中英

性能 - 在 javascript 中的过滤数组上使用相同条件的 foreach 与具有相同条件的过滤器和 foreach

[英]performance - foreach with condition inside vs filter with same condition and foreach on filtered array in javascript

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

选项1:

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

第一个选项是直截了当的。 I go 遍历所有记录,如果满足特定条件,则将所需值添加到 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。

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

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

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

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

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

请检查: 为什么使用 for 比 some() 或 filter() 更快

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

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

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

链接到源
基准测试:reduce()、filter()、map()、forloop 和 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']

暂无
暂无

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

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