You have a list of integers:
const integers = [1, 42, 7, 37, 2, ...]
Your goal is to separate odd and even numbers:
const separated = {
odd: [1, 7, 37, ...],
odd: [42, 2, ...],
}
function slow_solution(integers) {
return integers.reduce(
({ odd, even }, n) => {
if (n % 2 === 0) return { odd, even: [...even, n] };
return { odd: [...odd, n], even };
},
{ odd: [], even: [] }
);
}
Why is this slow?
We are creating a new array and new object on each iteration of the reduce callback.
function faster_reduce_solution(integers) {
return integers.reduce(
(res, n) => {
if (n % 2 === 0) res.even.push(n);
else res.odd.push(n);
return res;
},
{ odd: [], even: [] }
);
}
Why is that faster?
This mutates the arrays instead of creating new ones. So we avoided creating unneeded objects successfully.
if your coding style forces you not to mutate variables. You can avoid using .reduce
and use .filter
instead. Which is cleaner in my opinion:
function faster_filter_solution(integers) {
return {
odd: integers.filter((n) => n % 2 === 1),
even: integers.filter((n) => n % 2 === 0),
};
}
slow_solution | faster_reduce_solution | faster_filter_solution | |
1k integers | 5.216 ms | 0.247 ms | 0.215 ms |
10k integers | 57.073 ms | 0.541 ms | 0.638 ms |
100k integers | 27299.561 ms | 3.823 ms | 2.969 ms |
Benchmark run on Github actions