Understanding hidden classes in v8 » Debuggable

Posted on 1/9/10 by Felix Geisendörfer

Update: As pointed out by mraleph from the v8 team in the comments, some of the analysis here is probably flawed. See his post for more details: Understanding hidden classes in v8 - real picture

With JSConf.eu coming closer, I slowly have to start preparing my talk, which mostly means hacking on node-dirty.

I have a few goals for the project. My main interest is challenging a few assumptions people have about the performance and complexity of database systems. Most of that is material for another post and my talk itself, but today I'd like to talk about hidden classes in v8.

One of the things that is really fast in v8 is property lookups. This is due to an optimization that creates hidden classes for an object.

I could go into a lengthy explanation of how that works, but instead I'll invite you to see for yourself.

Consider the following two examples and guess which runs faster, and by how much:

Example 1:

var PROPERTIES = 10000000;
var o = {};

var start = +new Date;

for (var i = 0; i < PROPERTIES; i++) {
o[i] = i;
}

console.log(+new Date - start);

Example 2:

var PROPERTIES = 10000000;

function O(size) {
for (var i = 0; i < size; i++) {
this[i] = null;
}
}

var o = new O(PROPERTIES);

var start = +new Date;

for (var i = 0; i < PROPERTIES; i++) {
o[i] = i;
}

console.log(+new Date - start);

If you have guessed example 2, congratulations! Bonus points if you have also guessed that example 2 is a nifty 10x faster than example 1.

For those familiar with v8, you probably already know what is going. For those who don't, let me explain.

In example 1, every time you are setting a property on the o object, v8 is creating a new hidden class that defines the "data structure" of the o object to optimize property lookup performance.

In example 2, we are initializing these "hidden classes" the first time we create our o object. So when we are overwriting these properties later on, it is blazing fast, because v8 already knows how to efficiently lookup those properties.

So if you're writing node.js code, the lesson learned here is that it is much faster to work with existing properties in v8, than to add new ones.

In my next version of dirty I am planning to take advantage of this behavior by pre-allocating properties before they are actually used. This will probably require a little trickery to map user-defined keys to pre-allocated properties, but it should result in an overall 10x performance boost for setting new keys.

Let me know what you think / if you have other clever v8 hacks to speed stuff up : ).

--fg

PS: You can read more about hidden classes in the v8 docs.