25 Nov 2024 • 2 min read
I recently stumbled on this article that talks about a one line change that had a huge performance boost. The change? Removing the spread operator from within a loop.
I have regularly reached for the spread operator without too much thought, since it plays very nicely with an immutable style of JS programming1. However, after reading the article, I decided to do some digging into the performance of the operator. Pretty quickly it becomes apparent that the spread operator essentially runs in O(n)
time. Used one time, this isn't so bad–but when you start to use it within loops, it gets pretty bad. Take this example:
const users = [
{firstName: 'Alice', lastName: 'Church', age: 32},
{firstName: 'Bob', lastName: 'Lloyd', age: 55},
{name: 'Clarence', lastName: 'Tyson', age: 24},
];
const formattedUsers = users.map((user) => {
const fullName = getFullName(user);
const userWithFullName = {...user, fullName};
const createdAt = new Date();
const userWithCreationTime = {...userWithFullName, createdAt};
return userWithCreationTime;
});
I separated the creation of userWithFullName
from userWithCreationTime
because I have seen kind of approach before (and have done it myself!). When my eyes scan this code, I think "one loop, no big deal, O(n)
". But in reality, since there are two uses of the spread operator, it's O(2n^2)
😬
One fix would be to combine the two objects in one:
const formattedUsers = users.map((user) => {
const fullName = getFullName(user);
const createdAt = new Date();
return {
...user,
fullName,
createdAt
}
});
That is certainly an improvement, as it reduces the time to O(n^2)
. But the best solution here in my opinion is to embrace mutability2:
const formattedUsers = users.map((user) => {
user.fullName = getFullName(user);
user.createdAt = new Date();
return user;
});
The new solution is O(n)
.
If you can help it, don't use the spread operator in a loop.
"Immutable" is used loosely here since const
is not really immutable.
I realize that this isn't a cure-all; embracing mutability isn't appropriate in every situation. I recommend applying this approach judiciously.
Get my posts in your feed of choice. Opt-out any time.
If you enjoyed this article, you might enjoy one of these: