I’m trying to figure out the best way to to insert an element into a list.
I’ve come up with several approaches:
// setup
let messages = Array.from({ length: 1e5 }, (_, index) => ({ text: `text for message ${index + 1}` }));
The first tests don’t clone the original list.
const prependMessage1 = () => {
messages = [{ text:'test message 1' }, ...messages];
};
prependMessage1();
// 531 ops/s ± 4.61%
// 99.5 % slower
const prependMessage2 = () => {
messages = [{ text:'test message 2' }].concat(messages);
};
prependMessage2();
// 5.6K ops/s ± 1.49%
// 94.71 % slower
const prependMessage3 = () => {
messages.unshift({ text: 'text message 3' })
};
prependMessage3();
// 105K ops/s ± 1.25%
// Fastest ✅
const prependMessage4 = () => {
messages.reverse();
messages.push({ text: 'text message 4' });
messages.reverse();
};
prependMessage4();
// 4.9K ops/s ± 1.08%
// 95.3 % slower
I’m using a state manager in my app that doesn’t allow the mutation of the state directly. Each method should return a new object, not mutate the current list of messages. Now what’s interesting is that these results change once I start cloning:
const prependMessage1 = () => {
const copy = [...messages];
messages = [{ text:'test message 1' }, ...copy];
};
prependMessage1();
// 472 ops/s ± 3.19%
// 84.57 % slower
const prependMessage2 = () => {
const copy = [...messages];
messages = [{ text:'test message 2' }].concat(copy);
};
prependMessage2();
// 3.1K ops/s ± 1.09%
// Fastest ✅
const prependMessage3 = () => {
const copy = [...messages];
copy.unshift({ text: 'text message 3' })
messages = copy;
};
prependMessage3();
// 2.5K ops/s ± 2.28%
// 19.7 % slower
const prependMessage4 = () => {
const copy = [...messages];
copy.reverse();
copy.push({ text: 'text message 4' });
copy.reverse();
messages = copy;
};
prependMessage4();
// 1.2K ops/s ± 1.11%
// 61.14 % slower
Based on these tests, is it safe to assume that I should be using concat
? As the list grows, it seems as though concat
wins here. Or perhaps there’s another most optimal way that I’m missing?
2
Answers
So, based on these tests, it looks like using
concat
is a pretty solid choice for slapping a new element onto the start of your array, especially when you’re cloning things.The numbers show that
concat
is a champ in various situations, beating out the other methods most of the time.And hey, since your state manager is all strict about not messing directly with the state and wants a shiny new object each time,
concat
fits the bill perfectly.But, you know, don’t forget that real-life performance might throw a few surprises, and it’s not just about speed.
How your code reads and how easy it is to keep up are also important.
So, keep an eye on how things run in your app and do some regular testing to make sure everything’s smooth.
Hope you doing well, thanks.
Yes, seems
concat()
is the fastest. Btw you don’t need to copy the messages array in the case ofconcat()
and the spread syntax – they create a new copy.