所以,我已经广泛阅读了V8
引擎的公共Wiki,并且我得到了隐藏类如何查找属性的概念。 v8 design elements
但是,我真正得到的不仅仅是哈希表的速度。
根据这一点,它说的是属性存储在不同的偏移量中,但是对于每个偏移量,你必须检查它是否是正确的属性。那么是否意味着您必须迭代所有属性,在最坏的情况下,为您想要的属性获得正确的偏移量?
由于哈希表是常量时间查找,它们通常不会比这更快吗?
答案 0 :(得分:1)
您的问题似乎是通过here,here和here的某种组合来回答的。
简单地说,基于我对这些链接的理解:
Hashtables比常量时间查找慢,所以V8尽可能使用后者,但如果对象变得太复杂而无法使用隐藏类处理,则会回退到前者。
线性扫描显然也很糟糕,但在我看来,V8试图通过一种名为内联缓存的技术来优化代码来缓解数据结构的这个问题:当您的代码反复尝试访问obj.prop
时,V8最终决定只动态修补生成的代码,以便属性访问成为给定偏移量的恒定时间查找。
当然,如果预期的类类型错误,那么它必须退回并尝试慢速查找
this page function CompileNamedLoadFastProperty(klass, key)
试图解释:
function CompileNamedLoadFastProperty(klass, key) {
// Key is known to be constant (named load). Specialize index.
var index = klass.getIndex(key);
function KeyedLoadFastProperty(t, k, ic) {
if (t.klass !== klass) {
// Expected klass does not match. Can't use cached index.
// Fall through to the runtime system.
return NAMED_LOAD_MISS(t, k, ic);
}
return t.properties[index]; // Veni. Vidi. Vici.
}
return KeyedLoadFastProperty;
}
function NAMED_LOAD_MISS(t, k, ic) {
var v = LOAD(t, k);
if (t.klass.kind === "fast") {
// Create a load stub that is specialized for a fixed class and key k and
// loads property from a fixed offset.
var stub = CompileNamedLoadFastProperty(t.klass, k);
PatchIC("LOAD", ic, stub);
}
return v;
}