Suppose the following:
const getNewState = (state, messages) => {
const messagesToMerge = [];
messages.forEach((message) => {
const alreadyInState = state.find((messageInState) => messageInState.id === message.id);
if (!alreadyInState) {
messagesToMerge.push(message);
}
});
return [...messagesToMerge, ...state];
}
I would call the above like so:
const state = [
{
id: 1,
text: 'text 1'
},
{
id: 2,
text: 'text 2'
},
{
id: 3,
text: 'text 3'
},
];
const newState = getNewState(state, [
{
id: 1,
text: 'text 1'
},
{
id: 4,
text: 'text 4'
},
]);
The expected result:
[
{
id: 1,
text: 'text 1'
},
{
id: 2,
text: 'text 2'
},
{
id: 3,
text: 'text 3'
},
{
id: 4,
text: 'text 4'
}
]
Initially, however, I was using reduce
:
const getNewState = (state, messages) => {
const messagesToMerge = messages.reduce((acc, message) => {
const alreadyInState = acc.find((messageInState) => messageInState.id === message.id);
if (!alreadyInState) {
acc.push(message);
}
return acc
}, state);
return [...messagesToMerge, ...state];
}
My question is which of these two is faster? I ask because I’d imagine that even though state
is passed by reference to reduce
, it’s still cloned to be come the acc
, and if there are, say 10,000 messages, then it must be slower that a simple forEach
, right? Am I on the right track here or is there an altogether even better way of approaching this?
3
Answers
A more optimal solution: grab the IDs in the state into a set, and then filter them out:
When you want to know what is the faster, as AKX said, just test it
I wrote the three tests in JsPerf here:
The results are
EDIT: As AKX said, with a bigger amount of data (state 50 items, and 70 in stateToMerge), the fastest is the Set solution, and forEach is the slower
In order to actually measure them, you can loop with an index up to a very large number of your choice, perform both algorithms in the exact same amount and add up the times used for them. Then, compare the sums:
For me, the sum was:
You have an inner find, so the complexity is n * m, where n is the outer size and m is the size of data for which you run
.find
.However, whatever the result, the first approach is superior, because the second modifies your array and prevents you from reusing it.
You can optimize your algorithm of course, but for the purpose of this question, you were wondering about the comparison of the two algorithms.