Javascript引擎V8快速属性访问

Javascript引擎V8快速属性访问,javascript,v8,Javascript,V8,当我研究时,它在本主题的最后一段提到了这一点: 使用隐藏类有两个优点:属性访问没有 不需要字典查找,并且它们允许V8使用经典 基于类的优化,内联缓存 这对我来说有点模糊。有人能详细解释一下为什么隐藏类不需要字典查找,并允许v8使用经典的基于类的优化,即内联缓存吗 请尽可能详细地说明这一点。我认为隐藏类的概念在您提到的文章中得到了很好的解释。每当向对象添加新特性时,就会创建一个新的隐藏类。对象保留对此隐藏类的引用。此外,隐藏类还保留对先前创建的隐藏类的引用。例如: function Point(x

当我研究时,它在本主题的最后一段提到了这一点:

使用隐藏类有两个优点:属性访问没有 不需要字典查找,并且它们允许V8使用经典 基于类的优化,内联缓存


这对我来说有点模糊。有人能详细解释一下为什么隐藏类不需要字典查找,并允许v8使用经典的基于类的优化,即内联缓存吗


请尽可能详细地说明这一点。

我认为隐藏类的概念在您提到的文章中得到了很好的解释。每当向对象添加新特性时,就会创建一个新的隐藏类。对象保留对此隐藏类的引用。此外,隐藏类还保留对先前创建的隐藏类的引用。例如:

function Point(x, y) {
    this.x = x;
    this.y = y;
}

var point = new Point(10, 10);
调用
new Point()
时,将创建一个新的隐藏类,
Point
保留对该隐藏类的引用。初始隐藏类为空,这意味着它不包含任何属性。然后,当调用
this.x
时,将创建一个新的隐藏类。该隐藏类保留对上一个隐藏类的引用,point更新对该新隐藏类的引用。当执行
this.y=y
时,同样的情况再次发生

在JavaScript中,可以通过友好方式向对象添加和删除属性,解决属性访问的方法是使用映射。另一方面,隐藏类一个接一个地线性存储属性,就像C中的结构。由于隐藏类,访问属性的速度与访问数组元素的速度一样快

现在让我们来看看<强>内联缓存< /强>意味着什么。内联缓存是一种古老的优化技术,在动态语言(如Smalltak 80或Self)中使用,并由JavaScript推广。当在运行时访问属性时,有必要确定调用对象的类型,以便准确地知道要调用的实现代码。这称为动态分派或后期绑定,这是JavaScript在访问属性或对两个操作数求和(可以是整数、双精度等)时发生的情况。考虑下面的代码:

var x = 10;
var y = 10;
var total = x + y;
使用内联缓存时,当编译
var total=x+y
时,您不会在对通用加法子例程的过程调用中编译。相反,该代码被编译成存根(内联缓存)。内联缓存中生成的代码查看所接收参数的类型,并生成专门针对这些类型的代码。稍后,如果调用另一个加法,则执行内联缓存,假定类型与以前相同。但是,类型可能不同,因此内联缓存要做的第一件事就是检查参数的类型。如果类型不同导致缓存未命中,则会为这些特定类型生成新代码。如果内联缓存可以处理称为多态内联缓存的许多不同类型(一个具有多个类型集的条目)

内联缓存节省了在函数调用中推断参数类型的计算,例如,如果调用发生在循环中,则其好处更大

内联缓存在访问对象属性时发生在JavaScript中,在我们看到隐藏类如何帮助我们快速访问属性之前

有关隐藏类和内联缓存的更多信息,我推荐以下文章(特别是前两篇,来自V8 hacker Vyacheslav Egorov):


“有人能详细解释一下为什么隐藏类不需要字典查找吗”——因为那里没有字典。请阅读一次“快速物业访问”部分again@Bergi: