The Internal and Performance of JavaScript Arrays

The Internal and Performance of JavaScript Arrays

·

3 min read


In the previous article, the array basic was introduced. In this article, we will go a little deeper by looking into the internal and performance of arrays.


Array Internals

Arrays are ordered objects or objects are arrays if their keys are in order.

See the example below:

const arr = [ 'Bello', 27, 'Male', 'true' ];

console.log( arr[0] ); // Bello
console.log( arr[1] ); // 27
console.log( arr[2] ); // Male
console.log( arr[3] ); // true

typeof arr; // object

The example above in an object is represented below:

const obj = { 0: 'Bello', 1: 27, 2: 'Male', 3: true }

console.log( obj[0] ); // Bello
console.log( obj[1] ); // 27
console.log( obj[2] ); // Male
console.log( obj[3] ); // true

typeof obj; // object

Since arrays behave like objects, we can also copy arrays by reference.

See the example below:

const fruits = [ "Apple", "Orange" ]

const arr = fruits; // copy by reference

console.log(arr === fruits); // true

arr.push("Melon"); 

console.log(fruits); // [ 'Apple', 'Orange', 'Melon' ]

The internal representation of arrays allows an engine to store elements orderly in the contiguous memory area to make arrays fast.


Array Performance

Methods push/pop run fast, while shift/unshift are slow.

To prove the statement above, see the examples below:

const fruits = [ "Apple", "Orange", "Melon", "Banana" ];

console.log( fruits.shift() );

console.log(fruits); // [ 'Orange', 'Melon', 'Banana' ]

The example below shows what the above code passes through to remove the first element at the beginning of an array and then reorder them properly. See the example below:

const fruits = [ "Apple", "Orange", "Melon", "Banana" ];

// reordering elements due to the shift method on the fruits array 
fruits[0] = fruits[1]; // [ 'Orange', 'Orange', 'Melon', Banana ]
fruits[1] = fruits[2]; // [ 'Orange', 'Melon', 'Melon', Banana ]
fruits[2] = fruits[fruits.length-1]; 
// [ 'Orange', 'Melon', 'Banana', Banana ]
fruits[fruits.length-1] = fruits[fruits.length]; 
// [ 'Orange', 'Melon', 'Banana', undefined]

// remove only the last index element
console.log( fruits.pop() ); // undefined 
// => faster to remove an item with pop method

console.log(fruits); // [ 'Orange', 'Melon', 'Banana' ]

As you can see in the example above the pop method does not need to move anything, because other elements keep their indexes.

Adding/removing items from the end of an array (push/pop) are faster than adding/removing items from the beginning of an array (unshift/shift).


Array Loops

The old syntax to iterate through each item in an array is shown below:

const fruits = [ 'Orange', 'Melon', 'Banana' ];

for (let i = 0; i < fruits.length; i++) {
  console.log( fruits[i] );
}

/*
Orange
Melon
Banana
*/

The new and better syntax which was introduced in ECMAScript 2016 is shown below:

const fruits = [ 'Orange', 'Melon', 'Banana' ];

for (let fruit of fruits) {
  console.log(fruit);
}

/*
Orange
Melon
Banana
*/

Since arrays are objects, the for...in can be used to loop an array.

The above example is the same as below:

const fruits = [ 'Orange', 'Melon', 'Banana' ];

for (let fruit in fruits) {
  console.log( fruits[fruit] );
}

/*
Orange
Melon
Banana
*/

It is a bad practice to use for...in for array looping, use for...of instead. for...in is 10-100 times slower than for...of because of the extra iteration on properties and methods (which is not needed in an array looping).

We can also use a forEach method on an array to iterate on each item.

Syntax:

array.forEach(func)

where func = callback function.

See the example below:

const fruits = [ 'Orange', 'Melon', 'Banana' ];
const funcArray = (fruit) => {
  console.log(fruit);
};

fruits.forEach(funcArray);

/*
Orange
Melon
Banana
*/

Happy coding


image.png


image.png