Greetings v8-users,
I'm coming from the world of C, C++, x86_64 assembler, and native C-based OpenGL. I've switched gears recently and I'm doing a lot of JavaScript WebGL work now. Soon I'll be playing with V8 embedding so that I can run my JavaScript 3D projects in a native desktop environment. Other engines like SpiderMonkey, JavaScriptCore, and Chakra interest me as well.
I'm extraordinarily confused about the performance characteristics surrounding the objects-are-also-maps duality in JavaScript. I understand what hidden classes are in V8, and I get that there is no lookup overhead if you have something like a `Point` object and you access `this.x` or `this.y`. An engine like V8 will just do constant-offset access via the hidden class. My understanding of this is very V8-specific, but I imagine that other JavaScript engines play similar tricks.
What I'm confused about is the more complicated cases, and the subtleties. Here's a list of my various confusions. Points may overlap:
1) When exactly do objects go into dictionary mode? Are there general rules of thumb about this that can be applied to all engines that I'm likely to care about?
2) If global variables all exist as properties of the global object, then do JavaScript engines try hard to keep the global object out of dictionary mode? Top-level functions live on the global object too, I think, so if the global object is in dictionary mode then wouldn't a simple function call incur a dictionary lookup? That seems insane to me, but based on some IRC conversions I get the sense that this actually happens, a lot. Am I wrong here? I sure hope I'm wrong here.
3) I often see projects using objects in place of namespace. You'll see code like `new MyCorp.SomeClass()` and `MyCorp.DoIt()`. If the `MyCorp` object goes into dictionary mode then this would be pretty terrible. Fortunately namespace-y objects aren't likely to ever see a delete call, nor to be used as a dictionary-like way, so is it safe to assume that most engines will keep namespace-y objects in non-dictionary mode? Is this assumption safe even if the namespace-y object has upward of a thousand properties?
4) What do you do if the answer to #3 is "Yes, namespace-y objects often go into dictionary mode and incur lookup overhead"? My first thought is to put functions in the top-level instead, and just prefix them with the namespace: `new MyCorpSomeClass()` or `MyCorpDoIt()`. But then you're just using the global object itself as your namespace-y object, and if that can go into dictionary mode too then you're hosed either way. What's the solution here?
Based on previous unproductive conversations on IRC I feel the need to add the following warning to this post:
If your answer contains the phrases like "benchmark *then* optimize" or "care not about such things, crazy C programmer, this is JavaScript," then I'm going to reach out over the internet and steal your keyboard's enter key.
Thanks in advance for any help and advice!
-Patrick
1) When exactly do objects go into dictionary mode? Are there general rules of thumb about this that can be applied to all engines that I'm likely to care about?
2) If global variables all exist as properties of the global object, then do JavaScript engines try hard to keep the global object out of dictionary mode? Top-level functions live on the global object too, I think, so if the global object is in dictionary mode then wouldn't a simple function call incur a dictionary lookup? That seems insane to me, but based on some IRC conversions I get the sense that this actually happens, a lot. Am I wrong here? I sure hope I'm wrong here.
3) I often see projects using objects in place of namespace. You'll see code like `new MyCorp.SomeClass()` and `MyCorp.DoIt()`. If the `MyCorp` object goes into dictionary mode then this would be pretty terrible. Fortunately namespace-y objects aren't likely to ever see a delete call, nor to be used as a dictionary-like way, so is it safe to assume that most engines will keep namespace-y objects in non-dictionary mode? Is this assumption safe even if the namespace-y object has upward of a thousand properties?
4) What do you do if the answer to #3 is "Yes, namespace-y objects often go into dictionary mode and incur lookup overhead"? My first thought is to put functions in the top-level instead, and just prefix them with the namespace: `new MyCorpSomeClass()` or `MyCorpDoIt()`. But then you're just using the global object itself as your namespace-y object, and if that can go into dictionary mode too then you're hosed either way. What's the solution here?