如果 v8 在对象增长时重新散列
If v8 rehashes when an object grows
假设您对一个对象进行了更改,该更改会触发存储哈希值的基础数组或数据结构的大小发生更改。
var x = { a: 1, b: 2, c: 3 }
// trigger a resize theoretically
x.d = 4
x.e = 5
x.f = 6
假设哈希的底层数组在 v8 中看起来像这样
[ 1, 3, 2, null, null ]
它最初创建了一些额外的 space。但这还不够,所以它必须成长。有两种选择。
- 它在当前位置留下原始值。
- 它增长并重新散列,将值移动到任意新位置。
所以它看起来像:
// (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 ]
想知道 v8 在这种情况下会做什么。还想知道调整大小的启发式方法是什么(当它超出时它是否将数组大小加倍等)。
V8 引擎使用两种对象表示:
对于 属性 访问,快速模式通常要快得多 - 但需要知道对象的结构。
V8 最初会尝试构建一个对象的模板,称为 "Hidden Class"。该对象将通过隐藏 类 进行转换,直到 V8 放弃并将该对象存储为慢速 属性。
我在“Bluebird 的 util.toFastProperties 函数如何使对象的属性“快速”?
".
至于你的直接问题,对象会 "fast assign" 在那些 属性 分配上(在每个这样的分配上)并迁移到不同的映射(根据需要复制内存)。
V8 发布了一份关于如何存储属性的详细信息blogpost。
在字典属性 V8 的情况下(在您的示例中不是这种情况),底层数据结构是 hash map,因此底层数组中的实际位置发生变化。
但是,JavaScript 要求属性按插入顺序迭代。因此,每个字典目前都会跟踪它的插入位置,以按正确的顺序迭代条目。
V8 继续使用 2 的幂作为字典大小,并尽量使它们大致 50% empty 以避免频繁的哈希冲突。
假设您对一个对象进行了更改,该更改会触发存储哈希值的基础数组或数据结构的大小发生更改。
var x = { a: 1, b: 2, c: 3 }
// trigger a resize theoretically
x.d = 4
x.e = 5
x.f = 6
假设哈希的底层数组在 v8 中看起来像这样
[ 1, 3, 2, null, null ]
它最初创建了一些额外的 space。但这还不够,所以它必须成长。有两种选择。
- 它在当前位置留下原始值。
- 它增长并重新散列,将值移动到任意新位置。
所以它看起来像:
// (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 ]
想知道 v8 在这种情况下会做什么。还想知道调整大小的启发式方法是什么(当它超出时它是否将数组大小加倍等)。
V8 引擎使用两种对象表示:
对于 属性 访问,快速模式通常要快得多 - 但需要知道对象的结构。
V8 最初会尝试构建一个对象的模板,称为 "Hidden Class"。该对象将通过隐藏 类 进行转换,直到 V8 放弃并将该对象存储为慢速 属性。
我在“Bluebird 的 util.toFastProperties 函数如何使对象的属性“快速”? ".
至于你的直接问题,对象会 "fast assign" 在那些 属性 分配上(在每个这样的分配上)并迁移到不同的映射(根据需要复制内存)。
V8 发布了一份关于如何存储属性的详细信息blogpost。
在字典属性 V8 的情况下(在您的示例中不是这种情况),底层数据结构是 hash map,因此底层数组中的实际位置发生变化。
但是,JavaScript 要求属性按插入顺序迭代。因此,每个字典目前都会跟踪它的插入位置,以按正确的顺序迭代条目。
V8 继续使用 2 的幂作为字典大小,并尽量使它们大致 50% empty 以避免频繁的哈希冲突。