Javascript — Is There Any Difference on How You Add Items to Array?
Let’s see if there any difference between these ways to add items to array in Javascript:
arr.push(item);
arr[arr.length] = item;
If you already know the difference — continue reading maybe you find some new details you missed before 🤓
It’s obvious that you better use this approach:
arr.push(item);
The main reason is — built-in methods are very optimized and more preferable to be used.
But do you know exactly why it is better and what is the actual difference?
FUN FACTS!
const a = [];
orconst a = new Array();
creates empty array, but it allocates 4 slots in memory for future content; (see it in source code of V8 Engine — https://chromium.googlesource.com/v8/v8.git/+/refs/heads/master/src/objects/js-array.h#109)- when you set the element outside of array’s length (
arr[arr.length] =item;
) it usually allocates twice more memory and copies the array to new allocated memory range
Let’s find out some details
Arrays in Javascript are Objects and very basic Object structure looks like this (very simplified example as described here: https://stackoverflow.com/a/614255)
interface Object{
put(key, value)
get(key)
private: map properties // any data structure (hashtable, map, set etc...)
}
So Array will look like this:
interface Array:Object {
override put(key, value)
override get(key)
private:
map sparseStorage;
value[] flatStorage;
value length;
}
Where:
sparseStorage
is a map between integer indices and valuesflatStorage
is a native array of values
Speed comparison
I made 2 code samples to check the speed.
SAMPLE #1
// arr.push(item)const arr = [];
const iterationsTotal = 10000000;
console.time('arr.push(x)');
for(let i=0; i < iterationsTotal; i++){
arr.push(i + 'test');
}
console.timeEnd('arr.push(x)');
SAMPLE #2
// arr[arr.length] = itemconst arr = [];
const iterationsTotal = 10000000;
console.time('arr[arr.length] = x');
for(let i=0; i < iterationsTotal; i++){
arr[arr.length] = i + 'test';
}
console.timeEnd('arr[arr.length] = x');
In most cases SAMPLE #1 is ~9% faster.
To get better understanding why it is faster I made SAMPLE #3:
// arr[arr.length + ""] = itemconst arr = [];
const iterationsTotal = 10000000;
console.time('arr[arr.length + ""] = x');
for(let i=0; i < iterationsTotal; i++){
arr[arr.length+''] = i + 'test';
}
console.timeEnd('arr[arr.length + ""] = x');
And SAMPLE #3 is ~15% slower than SAMPLE #1
Explanation!
When you try to access the array element by the index, engine will try to convert the index to the Number and after that it will check if index is in the allowed range. Corresponding to V8’s source code the range is between 0 and 2³²-1.
You can see it here — https://chromium.googlesource.com/v8/v8.git/+/refs/heads/master/src/objects/js-array.h#131
It was added to V8 by Simon Zünd at this commit — https://chromium-review.googlesource.com/c/v8/v8/+/1126922/
Meanwhile arr.push(item)
doesn’t care about index’s format and value. It just takes the the length
property and increments it. That’s why it faster;
Conclusion
I don’t say you have always use array.push()
only, but you just need to know the difference.
Each problem has it’s own “good” solution and by knowing the difference of different approaches you can write more efficient code to solve the specific problem.
Good luck!
Photo in header by Danny Meneses from Pexels