Why is a double lookup faster than a single lookup in javascript?
Asked Answered
G

1

16

I am seeing some odd behavior in a jsperf test. Here is the setup:

var pro={};
pro._x=3;
var q=Object.create(pro);
q.x=3;
q.z={};
q.z.x=3;

Then I simply lookup each of the properties q.x, q._x, and q.z.x.

The single lookup q.x is faster than the prototype lookup q._x as expected. But the double lookup q.z.x is the fastest. I expected q.z.x to be the slowest, especially when compared to q.x.

q.z.x is even faster than q.z. What is going on here?

Gotcher answered 1/12, 2014 at 2:55 Comment(9)
Compiler optimisations…Irriguous
I know that are all of the same order of magnitude so not a big deal, but it doesn't make sense to me.Gotcher
Firefox 32 has oposite results, proto the faster, double lookup slowest. but much faster than chrome :)Shortly
It resembles an optimization like the oldie-but-goldie volatile. You reference that var twice, so you'll use it extensively (or at least, the optimizer thinks that)Cassius
In revision 4 of the test jsperf.com/8dfns4/4 where q.x=3 is moved to the last line, the double lookup is the slowest (Testing in Firefox 37.0).Clavus
I thought it was faster because q.<something> has multiple siblings, whereas q.<something>.<something> does not have siblings, so when doing a lookup on a property, it iterates over less items. But I was wrong about that, when adding multiple siblings to the object root, a double lookup is actually the same speed in Firefox: jsperf.com/8dfns4/7Laaspere
Curious, does the order of the lookup matter? like if you do q.x after q.z.x or some other way around?Chalcis
depends on browser. In Safari double look up is slowest.Wimble
see this revision of your code jsperf.com/8dfns4/11.Kerchief
C
1

The thing that makes the deeper lookup be faster is the fact that the JavaScript engine is able to better optimise the code for performance, as it knows exactly what object it is receiving.

Unlike using Object.create, where the engine is unable to perform its regular optimisation cycle, using a plain old empty object to initialise the z property of the q object, basically allows the engine to allocate appropriate memory and index it accordingly.

This piece of code var q=Object.create(pro); basically tells the JS engine: "Hey, you're getting an instance of an Object but I don't have a clue what type it is. Could be an Array, Objec, RegExp, Date.", while this piece of code -- q.z={}; says -- "Hey, you're getting an Object object here! Make sure to put aside some memory in accordance to this datatype".

Chalmer answered 13/5, 2015 at 13:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.