3 ms·
First off, JavaScript runtimes (or at least V8 and SpiderMonkey, which are the ones I've looked at) don't convert their arrays to hashtables unless they really
by bzbarsky 12y ago
First off, JavaScript runtimes (or at least V8 and SpiderMonkey, which are the ones I've looked at) don't convert their arrays to hashtables unless they really have to. If your array is not sparse and has no properties defined on it with non-integer names, then it's an actual array of values in memory.
Past that, even if you start defining non-integer names you still store the integer-named properties in a contiguous chunk of memory and store the named properties separately. This is why in V8 and SpiderMonkey the property order for an object (as seen by a for-in loop, say) doesn't match property addition order. Instead, the integer-named properties are enumerated first (in SpiderMonkey up to a certain limit) and then the other properties in addition order. So yes, the requirements are similar and JS engines throw some of them (property order preservation) under the bus to improve performance.
In SpiderMonkey, even once you have lots of properties (and are sparse and whatnot) and have converted to a hashtable, things are not that simple. The values are still stored in a contiguous memory buffer. There is a linked list of property descriptors which contain things like the property name and an index into the buffer, as well as metadata like whether the property is readonly and whatnot. This list is shared across objects that have the same property names added to them in the same order (though possibly with different values). What's stored in the hashtable, which can also be shared across objects is a mapping from property name to nodes in this linked list.
In practice, objects that have a dedicated hashtable just for that one object instead of sharing property descriptors with multiple other objects end up being pretty rare.
Lastly, JS engines are at least experimenting with unboxed storage for arrays. That is, instead of having a memory region filled with JS values, which might be of any type, detect at runtime that your array happens to only contain integers and have a memory region filled with integers; storing a non-integer will then cause a realloc and boxing of the data.
- esailija 12y agodoubles and SMis have been unboxed in arrays (the internal array that backs the integer key properties of an object) for a long time at least in V8.
- bzbarsky 12y agoAh, good to know. SpiderMonkey is in the process of adding that right now.
- gsnedders 12y ago> Lastly, JS engines are at least experimenting with unboxed storage for arrays. That is, instead of having a memory region filled with JS values, which might be of any type, detect at runtime that your array happens to only contain integers and have a memory region filled with integers; storing a non-integer will then cause a realloc and boxing of the data. FWIW, Carakan had typed "classes" for non-integer properties (often unboxing the majority of properties) from ~11.60, given it made relatively large memory savings when compared with the amount of RAM many TVs have (I've not paid enough attention around object representation to know if others are doing similar now?), and certainly unboxing arrays was talked about as part of the work to do that (though I'm not sure if we ever got around to implementing it; but one can probably see through performance side-channels).