简体   繁体   English

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

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

I have a question in performance.我有一个关于性能的问题。 Assume I have a massive array of objects called records .假设我有大量名为records的对象。 My goal is to create a Set (which makes sure that I have distinct values) that contains the value value of records from records that meet a certain condition - if(rec.otherValue === 'something specific') .我的目标是创建一个 Set (确保我有不同的值),其中包含满足特定条件的记录中records的值value - if(rec.otherValue === 'something specific') I have two possible ways that will yield the desired result:我有两种可能的方法可以产生预期的结果:

Option 1:选项1:

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

First option is straight-forward.第一个选项是直截了当的。 I go through all records and add the desired value to the Set if the specific condition is met. I go 遍历所有记录,如果满足特定条件,则将所需值添加到 Set 中。

Option 2:选项 2:

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

Second option first filters the massive records array in order to get a much more specific array of objects (from hundreds of records to less than 10), and then addidng the desired values to the Set.第二个选项首先过滤大量records数组以获得更具体的对象数组(从数百条记录到少于 10 条),然后将所需的值添加到 Set。

Both options yield the exact same result.这两个选项产生完全相同的结果。 My question is: which one is the best performance-wise?我的问题是:哪一个是性能最好的? My goal is to make the function as fast as possible.我的目标是尽可能快地制作 function。 And if there's a third, even faster option, please do share.如果有第三种,甚至更快的选择,请分享。

And what about this?那这个呢? I think it is highly readable and that is far more important as just the performance.我认为它具有很高的可读性,这比性能更重要。

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

If you want speed, Nothing beats native (vanilla) javascript when it comes to performance.如果您想要速度,就性能而言,没有什么比原生(香草)javascript 更好的了。 Then,然后,

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

Please check: Why using for is faster than some() or filter()请检查: 为什么使用 for 比 some() 或 filter() 更快

and

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

Testing this测试这个
I was curious about just how much faster the modern methods are, so I set up some tests on JSPerf.我很好奇现代方法的速度有多快,所以我在 JSPerf 上设置了一些测试。 Here's what I found:这是我发现的:

  • for loops and the forEach() method perform pretty close to each other. for 循环和forEach()方法的执行非常接近。
  • Methods like map() and filter() are about twice as fast as using forEach() and pushing to a new array to do the same thing. map()filter()等方法的速度大约是使用 forEach() 并推送到新数组以执行相同操作的速度的两倍。
  • Using forEach() for multi-step manipulation is about twice as fast as chaining methods like filter() and map() .使用forEach()进行多步操作的速度大约是filter()map()等链接方法的两倍。
  • These results were consistent across Chrome, Firefox, and Safari.这些结果在 Chrome、Firefox 和 Safari 中是一致的。 I was concerned that only the V8 JavaScript rendering engine had been optimized this way, but all modern browsers saw similar results.我担心只有 V8 JavaScript 渲染引擎以这种方式进行了优化,但所有现代浏览器都看到了类似的结果。

Link to source 链接到源
Benchmark for: reduce(), filter(), map(), forloop and forEach() 基准测试:reduce()、filter()、map()、forloop 和 forEach()

I tried running the benchmark multiple times and got the for loop as the slowest while forEach() and reduce() as the fastest.我尝试多次运行基准测试,结果 for 循环最慢,而forEach()reduce()最快。

There's another option you can use, with the use of reduce() .您可以使用另一个选项,使用reduce()

Here's an example:这是一个例子:

 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