JavaScript Micro Optimizations - Object, Hidden Class, and Array

JavaScript Micro Optimizations - Object, Hidden Class, and Array

Detail analysis of JavaScript object & Keys for performance optimization. JavaScript contains two fundamental data types: Primitives and Object. There are 7 primitive data types: string, number, bigint, boolean, null, undefined, symbol. Function, arrays, dates, and everything else are the object. V8 is Google’s open-source high-performance JavaScript and WebAssembly program/interpreter, written in C++. d8 is a command-line environment that is packaged with the v8 JavaScript engine. d8 is useful for running some JavaScript locally or debugging changes made to v8. In this blog post, the full picture of the object in v8 is analyzed with d8.

Primitives and Objects in JavaScript

JavaScript contains two fundamental data types: Primitives and Object. Data type defining immutable values(which cannot be altered) are primitives. They have no methods, stored in the stack, and compared by value. There are 7 primitive data types: string, number, bigint, boolean, null, undefined, symbol.

The rest are objects. They are mutable data types (can be altered) created by literals and compared by reference. They are the collection of properties, mapping between objects and keys, and values. Keys are string (or symbol) and value can be anything. Function, arrays, dates, and everything else are the object.

V8 and d8

V8 is Google’s open-source high-performance JavaScript and WebAssembly program/interpreter, written in C++. It is used in Chrome and in Node.js. The analysis and optimization techniques are based on the V8 engine which implements hidden class & inline cache. Other JavaScript engines implement similar approaches or hidden class variants. Safari JavaScriptCore has structures. Microsoft Edge’s ChakraCore has type. Firefox’ SpiderMonkey has shapes.

d8 is a command-line environment that is packaged with the v8 JavaScript engine. d8 is useful for running some JavaScript locally or debugging changes made to v8. In this blog post, the full picture of the object in v8 is analyzed with d8.

Analysis of Object

Let’s define an object named ‘test’ and debug it via d8.

var test = {
 a: “foo”,
 b: “bar”,
 0: “foo”,
 1: “bar”
}

Image for post

Fig. Object details in d8 shell

Findings

  • Named properties a & b with value “foo” and “bar” respectively.
  • Indexed properties *called *elements starting from 0 to 16, out of which 0 & 1 are holding “foo” & “bar” respectively.
  • Prototype information.
  • Map (Pointer to Hidden Class).

Named properties and indexed properties in JavaScript are treated separately. They have different usage patterns and stored in different memory locations.

Performance factor — Property Access Time

In lower-level programming languages like Java that have strong typing, the complete information of the object is known at compile time as object properties do not change at run time. The pointer to the object attributes can be stored in a contiguous buffer in a memory location with a fixed offset between each node and the length/size of the object can be known. In such a case, property access is not costly and can be done with a single instruction: at given memory offset, load the content.

Hidden Class

The property access mechanism in dynamically typed languages like JavaScript is different from strongly typed language, where object property can alter during run time. This requires a computationally expensive dynamic lookup. In V8, the object has a hidden class associated with it which works similarly to fixed object layout in Java, except they are created at run time and updated dynamically as object changes.

The hidden class serves the v8 engine primarily in two ways. First, the property access mechanism doesn’t require a dynamic lookup. Second, the hidden class provides an identifier for the shape of an object which serves a very important ingredient for V8’s optimizing compiler and inline caches.

Hidden Class Transition

The hidden class is dependent upon the order on which property is added to the object. However, adding array indexed properties doesn’t alter the hidden class. A hidden class knows which hidden class to refer to when a property is changed. If the same property gets added to the two objects sharing the same hidden class, both object receives the same new hidden class and all optimization associated with it. If the property of the object gets altered the transition information of objects hidden class is checked.

Let us consider a function named Point and define two objects p1 & p2. The transition of hidden classes occurs through a series of processes.

1\. function Point(x, y) {
2\.   this.x = x;
3\.   this.y = y;
4\. }
5\. 
6\. p1 = new Point(1,2);
7\. p2 = new Point(3,4);
  • When a function is declared, the object pointer for the function is formed, and hidden class *HC0 *(Hidden class 0) is created.

  • Line 6: when the code is executed to form object p1, it points to hidden class HC0.

  • Line 2: when the new property x is added and a new hidden class HC1 is formed. Similarly, when the property y is added another hidden class HC2 is created.

  • Line 7: while forming object p2, new hidden classes are not created but the hidden class pointer will successively point to HC0, HC1, and HC2.

    Image for post

Fig. Hidden Class Transition

Optimization Takeaways

Initialize objects member in the same order to avoid creating extra hidden class so that the same hidden class can be shared. It is inefficient to create hidden class whenever a property is added.
Adding properties to object after instantiation will cause hidden class transitions. Instead, assign all of the object properties during instantiation (as much as possible).

Inline Caching

v8 uses another optimization mechanism calledInline caching. The Object Access Site is any location in the program where object property is accessed (read or write). When an object property needs to be accessed, v8 has to perform a lookup to the hidden class associated with it (object) to determine the offset. This is a computationally expensive process.

The concept of inline caching is based upon the empirical formulae that the object accessed at any site often has the same hidden class, and the corresponding handler (to access the object property) is cached. After two successful calls to the same method to the same hidden class, it generates the handler routine. V8 performs an out-of-line approach for the inline cache. Rather than directly specializing the machine code, it creates a per-function data structure called IC Vector. For each object access site in the function, IC Vector contains one or more slots which contain the tuple(HC Addr, HC Handler). HC Address is a pointer to hidden class and Handler is a pointer that performs the operation for hidden class.

Image for post

Fig. IC Vector with 3 different access sites

In the beginning, the IC Vector is empty. As execution progress, the IC vector is filled whenever the object access site is encountered. An object access site that encounters only the object of a single hidden class is monomorphic. If the site encounters objects of multiple hidden classes, then it is polymorphic.

Optimization Takeaway

Prefer monomorphic over the polymorphic object access site for better performance. Prefer function call with same type of objects.

javascript web-development react node developer

Bootstrap 5 Complete Course with Examples

Bootstrap 5 Tutorial - Bootstrap 5 Crash Course for Beginners

Nest.JS Tutorial for Beginners

Hello Vue 3: A First Look at Vue 3 and the Composition API

Building a simple Applications with Vue 3

Deno Crash Course: Explore Deno and Create a full REST API with Deno

How to Build a Real-time Chat App with Deno and WebSockets

Convert HTML to Markdown Online

HTML entity encoder decoder Online

How native is React Native? | React Native vs Native App Development

Article covers: How native is react native?, React Native vs (Ionic, Cordova), Similarities and difference between React Native and Native App Development.

Hire Node.JS Developers | Skenix Infotech

We are providing robust Node.JS Development Services with expert Node.js Developers. Get affordable Node.JS Web Development services from Skenix Infotech.

Hire Dedicated React Native Developer

Have you ever thought of having your own app that runs smoothly over multiple platforms? React Native is an open-source cross-platform mobile application framework which is a great option to create mobile apps for both Android and iOS. **[Hire...

Hire Dedicated React Native Developer in India | React Native Development

Hire dedicated React Native developers for your next project. As the top react native development company we offer you the best service as per your business needs.

Web Development | React, Node.js and MySQL Tutorial for Beginners

React Components will help you in understanding the fundamentals of components in ReactJS. Node.js MySQL Tutorial will help you in learning how to connect to a MySQL database from your Node.js application with practical demonstration.