问题
Say you have a change in an object that triggers a change in the size of the underlying array or data structure storing the hash values.
var x = { a: 1, b: 2, c: 3 }
// trigger a resize theoretically
x.d = 4
x.e = 5
x.f = 6
Say the underlying array for the hash looked like this in v8
[ 1, 3, 2, null, null ]
It created some extra space initially. But it wasn't quite enough so then it had to grow. There are two options.
- It grows leaving the original values in there current place.
- It grows and rehashes, moving the values to arbitrary new places.
So it would look like:
// (1) 1, 3, 2 stay where they are
[ 1, 3, 2, 6, 4, 5, null, null, null, null ]
// (2) 1, 3, 2 are moved
[ 6, 2, 5, 3, 4, 1, null, null, null, null ]
Wondering what v8 does in this situation. Also wondering what the heuristics are for the resizing (does it double the array size when it outgrows, etc.).
回答1:
The V8 engine uses two object representations:
- Dictionary mode - in which object are stored as key - value maps as a hash map.
- Fast mode - in which objects are stored like structs, in which there is no computation involved in property access.
Fast mode is typically much faster for property access - but requires the object's structure to be known.
V8 will initially try to construct a template of what the object looks like called a "Hidden Class". The object will transform through hidden classes until V8 will give up and store the object as a slow property.
I go into this more in depth with the relevant code in "How does Bluebird's util.toFastProperties function make an object's properties “fast”? ".
As for your direct question the object would "fast assign" on those property assignments (on each such assignment) and migrate to a different map (copying the memory as needed).
回答2:
V8 has published a detailed blogpost on how they store properties.
In the case of dictionary properties V8 (which would not be the case in your example) the underlying data structure is a hash map and thus the actual location in underlying array changes.
However, JavaScript demands that properties are iterated in insertion order. Hence, each dictionary currently keeps track of it's insertion position to iterate the entries in the proper order.
V8 keeps uses powers of 2 for the dictionary sizes and tries to keep them roughly 50% empty to avoid frequent hash collisions.
来源:https://stackoverflow.com/questions/50011721/if-v8-rehashes-when-an-object-grows