10 ms·
V8/Chrome uses the constructor as a big part of the heuristic that determines the 'hidden class' of an object. The other part of the heuristic is the names and
by ErikCorry 16y ago
V8/Chrome uses the constructor as a big part of the heuristic that determines the 'hidden class' of an object. The other part of the heuristic is the names and ordering of the properties on the object.
Unfortunately, JSlint creates all its objects with Object.create and not with a constructor function. This causes objects with a similar structure to have a different 'hidden class'. This causes most of the optimizations in V8 to break down.
This is definitely a fixable problem and the benchmark is a good illustratiom of the issue. I'm not sure if the benchmark illustrates 'actual performance' more than any other benchmark, but it does seem to illustrate something that should go fast. In this respect it is ahead of Kraken 1.0 which illustrates how fast you can multiply NaN with undefined.
- kingkilr 16y agoI don't see why it's an issue that Object.create is used, as long as attributes are assigned in a consistent order the optimization should still hold, since each assignment (or read) site would be monomorphic with respect to the current map (to use the Self terminology), even if the type isn't a useful indicator. (If I'm horribly off let me know, I'm using my knowledge of PyPy to try to make some guesses about how precisely V8 applies these techniques).
- vr 16y agoIn V8 Object.create(arg) is implemented roughly as var o = {}; o.__proto__ = arg. The first statement sets the default hidden class for the newly created object. Since hidden classes in V8 capture the prototype structure as well, it has to change in the second statement. Now the problem is that unlike with normal properties no hidden class transition happens and we get a brand new hidden class each time.
- allenwb 16y agoInterestingly, the 2nd argument to Object.create was specifically designed (by me) so that an object's "shape" could be statically determined. If the descriptor is all literals (they usually are) then each Object.create call site is essentially a construction site for a "class" of objects that share a common structure. As Erik says, this should be fixable. It sounds to me like Crock's coding style is just ahead of the engine implementation curve. Hopefully it will help push this optimization into the actual implementations.
- mraleph 16y agoCrockford's code style is very peculiar: https://github.com/douglascrockford/JSLint/blob/master/jslint.js#L1494-1536 https://github.com/douglascrockford/JSLint/blob/master/jslin... (I really hope that this is not coding-style-of-the-future) As you can see single Object.create callsite becomes a construction site for objects that might _not_ share a common structure (they potentially have different prototypes).