Chrome performance: “standard” property names vs. non-standard

Chrome performance: “standard” property names vs. non-standard

So this is an interesting one… While I was testing the performance of setAttribute vs. normal property set on an element, I found an odd behavior, which I then tested on regular objects and… It’s still odd!
So if you have an object A = {},
and you set its property like A[‘abc_def’] = 1, or A.abc_def = 1, they are basically the same.
But then if you do A[‘abc-def’] = 1 or A[‘123-def’] = 1 then you are in trouble. It goes wayyy slower.
I set up a test here: They all work the same on all browsers except chrome.
The funny thing is that for “abc_def” property, chrome is actually much faster than Firefox and IE, as I expected. But for “abc-def” it’s at least twice as slow.
So what happens here basically (at least from my tests) is that when using “correct” syntax for properties (legal C syntax, which you can use with dot properties) – It’s fast, but when you use syntax that requires using brackets (a[…]) then you’re in trouble.
I tried to imagine what implementation detail would distinguish in such a way between the two modes, and couldn’t. Because as I think of it, if you do support those non-standard names, you are probably translating all names to the same mechanics, and the rest is just syntax which is compiled into that mechanic. So . syntax and [] should be all the same after compilation. But obviously something is going the other way around here…
Without looking at V8’s source code, could anyone think of a really satisfying answer? (Think of it as an exercise :-))
Here’s also a quick example
Thanks to NDM for the jsperf example!

To clarify, of course I want also a concrete answer from the real code
(which I already found) or to be more precise – the reason behind that
specific implementation. That is one of the reasons I asked you to
look at it “as an exercise”, to look behind the technical
implementation and try to find the reason.
But I also wanted to see how other people’s minds work in cases like these.
This may sound “vague” to some of you – but it is very useful to try and think
like other people from time to time, or take their point of view. It
enhances your own ways of thinking.


Solution 1:

So JS objects can be used for two conflicting purposes. They can be used as objects but they can be used as hash tables too. However what is fast and makes sense
for objects is not so for hash tables, so V8 tries to guess what a given object is.

Some signs the user can give that he wants a dictionary are deleting a property or giving a property a name that cannot be accessed using dot notation.

Some other heuristics are also used, I have made a gist

There is however a really cool hack that redempts an object from hash table hell:

function ensureFastProperties(obj) {
    function f() {}
    f.prototype = obj;
    return obj;

See it in action:

The redempted object is not as fast as the original because the properties are stored in the external properties array rather than in-object. But that’s still far better than hash table. Note that this is still pretty broken benchmark, do not think for a second that hash tables are only 2x slower than inobject properties.