使用 javascript Array reduce() 方法有什么真正的好处吗? [英] Is there any real benefit for using javascript Array reduce() method?
问题描述
reduce() 方法的大多数用例都可以用 for 循环轻松重写.在 JSPerf 上的测试表明,reduce() 通常慢 60%-75%,具体取决于每次迭代中执行的操作.
Most use cases of the reduce() method can be easily rewritten with a for loop. And testing on JSPerf shows that reduce() is usually 60%-75% slower, depending on the operations performed inside each iteration.
那么,除了能够以函数式风格"编写代码之外,还有其他真正的理由使用 reduce() 吗?如果您可以通过编写多一点代码获得 60% 的性能提升,为什么还要使用 reduce()?
Is there any real reason to use reduce() then, other than being able to write code in a 'functional style'? If you can have a 60% performance gain by writing just a little bit more code, why would you ever use reduce()?
事实上,其他函数方法如 forEach() 和 map() 都表现出相似的性能,至少比简单的 for 循环慢 60%.
In fact, other functional methods like forEach() and map() all show similar performance, being at least 60% slower than simple for loops.
这是 JSPerf 测试的链接(带有函数调用):forloop vs forEach
Here's a link to the JSPerf test (with function calls): forloop vs forEach
推荐答案
方法的性能可能会因数据的大小而异.速度还受到编译器优化和数据预热的影响.因此,在小数据上for of
获胜,而在大数据上reduce
微不足道.
The performance of the methods may vary depending on the size of the data.
Speed is also affected by compiler optimization and data warm-up.
Therefore on small data for of
wins, and on big reduce
insignificantly wins.
您可以通过运行测试亲自查看:
You can see for yourself by running the test:
const LOOP = 3
test(dataGenerator(5))
test(dataGenerator(500))
test(dataGenerator(50000))
test(dataGenerator(500000))
test(dataGenerator(5000000))
function test(dataSet) {
let sum
console.log('Data length:', dataSet.length)
for (let x = 0; x < LOOP; x++) {
sum = 0
console.time(`${x} reduce`)
sum = dataSet.reduce((s, d) => s += d.data, 0)
console.timeEnd(`${x} reduce`)
}
for (let x = 0; x < LOOP; x++) {
sum = 0
console.time(`${x} map`)
dataSet.map((i) => sum += i.data)
console.timeEnd(`${x} map`)
}
for (let x = 0; x < LOOP; x++) {
sum = 0
console.time(`${x} for loop`)
for (let i = 0; i < dataSet.length; i++) {
sum += dataSet[i].data
}
console.timeEnd(`${x} for loop`)
}
for (let x = 0; x < LOOP; x++) {
sum = 0
console.time(`${x} for reverse`)
for (let i = dataSet.length; i--;) {
sum += dataSet[i].data
}
console.timeEnd(`${x} for reverse`)
}
for (let x = 0; x < LOOP; x++) {
sum = 0
console.time(`${x} for of`)
for (const item of dataSet) {
sum += item.data
}
console.timeEnd(`${x} for of`)
}
for (let x = 0; x < LOOP; x++) {
sum = 0
console.time(`${x} for each`)
dataSet.forEach(element => {
sum += element.data
})
console.timeEnd(`${x} for each`)
}
console.log()
}
function dataGenerator(rows) {
const dataSet = []
for (let i = 0; i < rows; i++) {
dataSet.push({id: i, data: Math.floor(100 * Math.random())})
}
return dataSet
}
这些是在我的笔记本电脑上进行性能测试的结果.for 循环
不像 for reverse
和 for of
那样工作不稳定.
These are the results of a performance test on my laptop.
for loop
does not work stably unlike for reverse
and for of
.
➜ node reduce_vs_for.js
Data length: 5
0 reduce: 0.127ms
1 reduce: 0.008ms
2 reduce: 0.006ms
0 map: 0.036ms
1 map: 0.007ms
2 map: 0.018ms
0 for loop: 0.005ms
1 for loop: 0.014ms
2 for loop: 0.004ms
0 for reverse: 0.009ms
1 for reverse: 0.005ms
2 for reverse: 0.004ms
0 for of: 0.008ms
1 for of: 0.004ms
2 for of: 0.004ms
0 for each: 0.046ms
1 for each: 0.003ms
2 for each: 0.003ms
Data length: 500
0 reduce: 0.031ms
1 reduce: 0.027ms
2 reduce: 0.026ms
0 map: 0.039ms
1 map: 0.036ms
2 map: 0.033ms
0 for loop: 0.029ms
1 for loop: 0.028ms
2 for loop: 0.028ms
0 for reverse: 0.027ms
1 for reverse: 0.026ms
2 for reverse: 0.026ms
0 for of: 0.051ms
1 for of: 0.063ms
2 for of: 0.051ms
0 for each: 0.030ms
1 for each: 0.030ms
2 for each: 0.027ms
Data length: 50000
0 reduce: 1.986ms
1 reduce: 1.017ms
2 reduce: 1.017ms
0 map: 2.142ms
1 map: 1.352ms
2 map: 1.310ms
0 for loop: 2.407ms
1 for loop: 12.170ms
2 for loop: 0.246ms
0 for reverse: 0.226ms
1 for reverse: 0.225ms
2 for reverse: 0.223ms
0 for of: 0.217ms
1 for of: 0.213ms
2 for of: 0.215ms
0 for each: 0.391ms
1 for each: 0.409ms
2 for each: 1.020ms
Data length: 500000
0 reduce: 1.920ms
1 reduce: 1.837ms
2 reduce: 1.860ms
0 map: 13.140ms
1 map: 12.762ms
2 map: 14.584ms
0 for loop: 15.325ms
1 for loop: 2.295ms
2 for loop: 2.014ms
0 for reverse: 2.163ms
1 for reverse: 2.138ms
2 for reverse: 2.182ms
0 for of: 1.990ms
1 for of: 2.009ms
2 for of: 2.108ms
0 for each: 2.226ms
1 for each: 2.583ms
2 for each: 2.238ms
Data length: 5000000
0 reduce: 18.763ms
1 reduce: 17.155ms
2 reduce: 26.592ms
0 map: 145.415ms
1 map: 135.946ms
2 map: 144.325ms
0 for loop: 29.273ms
1 for loop: 28.365ms
2 for loop: 21.131ms
0 for reverse: 21.301ms
1 for reverse: 27.779ms
2 for reverse: 29.077ms
0 for of: 19.094ms
1 for of: 19.338ms
2 for of: 26.567ms
0 for each: 22.456ms
1 for each: 26.224ms
2 for each: 20.769ms
这篇关于使用 javascript Array reduce() 方法有什么真正的好处吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!