In the case of the JavaScript engine, V8 is a very good one. In this article, I present the results of my small study of the effectiveness of one of the internal optimizations of V8.V8 mechanism description
Before you continue reading, I advise you to read About the internal device of V8 and code optimization in order to better understand the essence of what is happening.To make it very simple, V8 builds objects using internal hidden classes. Each such class corresponds to a unique object structure. For example, if we have a code like this:
const obj = {}
obj.a = 1
obj.b = 2
obj.c = 3
The engine caches these class chains, and if you re-create the object with the same field names and the same order, it will not create hidden classes again, but will use existing ones. In this case, the property values ββthemselves may differ.
const obj2 = {}
obj2.a = 4
obj2.b = 5
obj2.c = 6
However, this behavior is easy to break. It is enough to define the same object, but with fields in a different order
const obj3 = {}
obj3.c = 7
obj3.a = 8
obj3.b = 9
Next, I tried to test and determine the difference in performance when working with objects in which the field names coincide and in which they differ.Test method
I conducted three groups of tests:- Static - property names and their order did not change.
- Mixed - only half of the properties changed.
- Dynamic - all properties and their order were unique for each object.
results
Time to create one object
The first, most important and simple test: I took a cycle of 100 iterations. In each iteration, I created a new object and measured the time it took to create it for each iteration.
Timeline for creating one object depending on iterationAs you can see, during the first cold start in all groups, creating an object takes almost identical time. But already at the second or third iteration, the execution speed in the static and mixed groups (where V8 can apply optimization) compared with the dynamic group significantly increases.And this leads to the fact that thanks to the internal optimization of V8, the 100th object from the static group is created 7 times faster.Or, you could say it another way:not following the order in which properties are declared in identical objects can slow down your code sevenfold .
The result does not depend on how exactly you create the object. I tried several different methods and they all gave almost identical values.const obj = {}
for (let key of keys) obj[key] = 42
const obj = new createObject(keys)
const obj = Object.fromEntries(entries)
const obj = eval('({ ... })')
Total time to create multiple objects
In the first test, we found that an object from the dynamic group can be created 30-40 microseconds longer. But this is only one object. And in real applications there can be hundreds or thousands of them. We calculate the total overhead costs at different scales. In the next test, I will sequentially repeat the first, but measure not the time to create one object, but the total time to create an array of such objects.
Timeline for creating an array of objects depending on its sizeAs you can see, on the scale of the entire application, a simple internal optimization of V8 can accelerate tens of times.Where is it important
Everywhere. In JavaScript, objects are everywhere. Here are a few life examples where maintaining a property order will give you a performance boost:When working with Fetchfetch(url1, {headers, method, body})
fetch(url2, {method, headers, body})
When working with jQuery$.css({ color, margin })
$.css({ margin, color })
When working with VueVue.component(name1, {template, data, computed})
Vue.component(name2, {data, computed, template})
When working with the Composite pattern (layout)const createAlligator = () => ({...canEat(), ...canPoop()})
const createDog = () => ({...canPoop(), ...canEat()})
And in a great many other places.Just following the order of properties in objects of the same type will make your code more productive.References
Test code and detailed resultsAbout V8 internals and code optimization