Reputation: 1083
Inspired by this question:
replace filter and map with reduce es6
I decided to test if reduce
is faster than filter
plus map
on given example.
I made a fiddle:
var data = Array(10 ** 4).fill(null).map((_, i) => {
return {
checked: Math.random() < 0.5,
val: Math.floor(Math.random() * 10000)
}
})
f1 = () => {
t0 = performance.now();
data.filter(el => el.checked).map(el => el.val)
t1 = performance.now();
// console.log("filter plus map took " + (t1 - t0) + " milliseconds.")
document.getElementById('filterPlusMap').innerText = t1 - t0;
}
f2 = () => {
t0 = performance.now();
data.reduce((prev, curr) => {
return curr.checked ? [...prev, curr.val] : prev
}, [])
t1 = performance.now();
// console.log("reduce took " + (t1 - t0) + " milliseconds.")
document.getElementById('reduce').innerText = t1 - t0;
}
f1();
f2();
<div>Filter plus map: <span id='filterPlusMap'></span> milliseconds</div>
<div>Reduce: <span id='reduce'></span> milliseconds</div>
and it turned out that reduce
is like 100 times worse...
But then I changed assignment method in reduce
and it turned out to be better than filter+map in next fiddle (like 4 times better):
var data = Array(10 ** 6).fill(null).map((_, i) => {
return {
checked: Math.random() < 0.5,
val: Math.floor(Math.random() * 10000)
}
})
f1 = () => {
t0 = performance.now();
data.filter(el => el.checked).map(el => el.val)
t1 = performance.now();
// console.log("filter plus map took " + (t1 - t0) + " milliseconds.")
document.getElementById('filterPlusMap').innerText = t1 - t0;
}
f2 = () => {
t0 = performance.now();
data.reduce((prev, curr) => {
return curr.checked ? (prev.push(curr.val), prev) : prev
}, [])
t1 = performance.now();
// console.log("reduce took " + (t1 - t0) + " milliseconds.")
document.getElementById('reduce').innerText = t1 - t0;
}
f1();
f2();
<div>Filter plus map: <span id='filterPlusMap'></span> milliseconds</div>
<div>Reduce: <span id='reduce'></span> milliseconds</div>
Can someone pls:
(prev.push(curr.val), prev)
is so much better? And should it be used?reduce
should be always prefered over filter+map
?Upvotes: 6
Views: 5070
Reputation: 351328
Explain why it changed so much between the fiddles? I.e. - why
(prev.push(curr.val), prev)
is so much better? And should it be used?
(arr.push(val), arr)
is much faster than [...arr, val]
as the latter copies the whole arr
array into a new array, giving the reduce
operation a O(n²) time complexity. The first only has to add 1 element to the existing arr
, ... this gives a O(n) time complexity to the whole reduce
operation.
Tell if
reduce
should be always preferred overfilter
+map
?
No, this really depends on the logic to be applied and what requirements you have in terms of performance. And readability also counts: filter
and map
tend to be a bit more readable (understandable) than reduce
.
Upvotes: 13