Improving Javascript Performance by Understanding V8

krishcdbry
5 min readJul 29, 2019

--

Before going into the performance optimization tips, Let’s discuss what is V8?

V8 is an open-source high-performance Javascript engine, Created by Lars Bak (Danish computer programmer currently employed by Google).
* It was written in C++ and used in big projects like Couchbase, Node.js, etc.
* It implements ECMAScript (ECMA-262)
* It became most famous Javascript engine because the main differences between V8 and other Javascript engines are that V8 doesn’t produce bytecode or intermediate code, It directly compiles Javascript code to native machine code before executing it.
* It consists of Ignition interpreter and TurboFan (Optimizing compiler) which makes V8 the KING

Javascript does not have explicit types, hence it is a bit difficult to improve the performance because the gathering the information of types quickly is hard during the compilation process because for Javascript the compilation is a part of the execution. So we need to find ways to improve this. However, there are some tricks.

Hidden Class

Javascript is a prototype-based language.
There are no classes, objects are created by the cloning process. Instead of using a dictionary-like data structure for storing object properties and then doing a dynamic loop to resolve the property location,

V8 internally creates main hidden classes for objects at runtime.
Objects with same hidden class can use the same optimized generated code

For every new property added V8 creates new hidden class keeping the old class for reference

After adding new property a new class will be created from Person
[ name, age, salary] // Now for both person1, person2 references will be changed to this new class. Because of this Inline Caching (IC’s) assumptions will change (i.e Optimized generated code need to re-optimize)

Techniques to improve performance :

* For every new property added to an existing object, V8 creates new hidden class, So to improve the Javascript performance we can stop adding new property after the object creation.

* Initialize all object members in constructor functions

* Always initialize object members in same order

Arrays

V8 handles arrays using methods
A. Fast Elements (For arrays where Set of keys very compact, having linear storage buffer).
B. Dictionary Elements (Designed for sparse arrays — hash table).

Techniques to improve performance :

* Use contiguous keys starting at 0 for Arrays.

* Don’t pre-allocate large Arrays ( > 64k elements) let them grow as you go.

* Removing elements from array then performance increases. (Don’t delete elements in Arrays)

* Avoid loading uninitialized or deleted elements.

Example

But Arrays of doubles slow because of tagging
1. Arrays hidden class tracks element types.
2. Arrays containing only doubles are unboxed.
3. Unboxing causes are hidden the class change. So careless multiplication of Array may cause extra work due to boxing and unboxing.

Hidden classes for elements — Trouble ahead

Techniques to improve performance :

* Initialize using array literals for small fixed-sized arrays.

* Pre-allocate small arrays to correct size before using them.

* Dont store non-numeric values (objects) in numeric arrays.

Compilers

V8 Has two compilers
1. Full Compiler (Baseline)
2. Optimizing Compiler

1. Full Compiler — That can generate good code for any Javascript, but not great JIT Code. Its goal is to generate code quickly. To achieve the goal it doesn’t do any type of analysis and doesn’t know anything about types. It uses Inline Caches (IC) to refine knowledge about type while the program runs and it improves the speed 20 times.

IC Handles types efficiently
– Type dependent code for operations.
– Validate type assumptions first and then do work.
– Change at runtime via backpatching as more types are discovered.

Monomorphic is always better than polymorphic

If the hidden classes are always the same then it is monomorphic if not polymorphic.

2. Optimizing compiler — This produces great code. It comes later and recompiles hot functions. It uses IC (Inline cache) to know about types and makes decisions about how to optimize the code better.

Small change makes a big difference

Now let’s modify our algorithm a little.

See, We can Improve Javascript executing speed with a small change in our Algorithm — So Optimize the Javascript Algorithm.

Techniques to improve performance :

* V8 also supports deOptimization: The optimizing compiler makes optimistic assumptions from the inline cache but it may fail sometimes so in those cases V8 throws away the optimized code and comes back to the Full compiler to get types again from the ICs. This process is slow and should be avoided by trying not to change the functions once they are optimized.

These are few tips to improve the Javascript performance, we can go deep in V8 to get more stuff.

Resource
Slides by Daniel Clifford, tech lead and manager of the V8 team

--

--

krishcdbry
krishcdbry

Written by krishcdbry

Director Of Engineering @ Bharatpe. Geeky Ninja — Breathing Code, Dreaming Optimisation, Building Crazy Stuff & always up for new Challenges.

No responses yet