VahagnNikoghosian VahagnNikoghosian - 5 months ago 12
Javascript Question

Why array of objects whose property initialized with null process better

I noticed some unexpected result during working with big arrays in js. In my test I'm creating big array of some class instances with for loop and within loop I'm assigning same string to all object's "x" property and after array initialization doing some calculation with this array. If constructor initializes "x" property with null, array always processing better, even if it's doing extra statement. Why this is happening ?
Here is my code for testing. I tested in on chrome.

function f1() {
var P = function () {
this.value = 1
};
var big_array = new Array(10000000).fill(1).map((x, index)=> {
p = new P();
if (index > 5000000) {
p.x = "some_string";
}

return p;
});
big_array.reduce((sum, p)=> sum + p.value, 0);
}

function f2() {
var P = function () {
this.value = 1;
this.x = null;
};
var big_array = new Array(10000000).fill(1).map((x, index)=> {
p = new P();
if (index > 5000000) {
p.x = "some_string";
}

return p;
});
big_array.reduce((sum, p)=> sum + p.value, 0);
}


(function perform(){
var start = performance.now();
f1();
var duration = performance.now() - start;

console.log('duration of f1 ' + duration);


start = performance.now();
f2();
duration = performance.now() - start;

console.log('duration of f2 ' + duration);
})()


Output:

duration of f1 14099.85
duration of f2 11694.175000000001

Answer

In my Firefox browser f2 runs approximately 4 times faster than f1. The reason is that the Just-in-Time JavaScript compiler tries to optimise code based on expected object structures. As mentioned on mdn:

Fortunately, objects and properties are often "predictable", and in such cases their underlying structure can also be predictable. JITs can rely on this to make predictable accesses faster.

This predicting will of course work better if properties are "declared" within the object constructor, which is where the optimiser will look for doing its magic.

Once a structure is assumed, it becomes more costly to still added a property "later".

However, there are different engines out there, which have different optimisers, and so this result can be very different on different browsers. But it seems good practice to include the definition of properties in the constructor, even when their value is not yet known.

This will bring improvement for those engines that benefit from that, and will not bring much of a cost in performance on other engines. Also it may increase readability of your code.