2013-03-25 130 views
2

当我看进v8 design elements of fast property access,它提到了这个主题的最后一段了这一点:JavaScript引擎V8快速访问属性

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

这对我来说有点模糊。任何人都可以详细说明为什么隐藏类不需要字典查找,并启用V8使用经典的基于类的优化,内联缓存?

请尽可能详细地做到这一点。

+3

“任何人都可以详细说明为什么隐藏类不需要字典查找”---因为这里没有字典。请再次阅读“快速访问”部分 – zerkms 2013-03-26 02:06:16

+0

@Bergi:https://developers.google.com/v8/design – zerkms 2013-03-26 02:06:40

回答

3

我认为隐藏类的想法你提到的文章中进行了很好的解释。无论何时将新属性添加到对象时,都会创建一个新的隐藏类。该对象保持对这个隐藏类的引用。此外,隐藏类也保持到先前创建的隐藏类的引用。例如:

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

var point = new Point(10, 10); 

new Point()被称为新隐藏类被创建,并point保持到是隐藏类的引用。那最初隐藏类是空的,也就是说,它不包含任何属性。然后,当调用this.x时,将创建一个新的隐藏类。这个隐藏的类保持对前一个隐藏类的引用,并且更新其对该新的隐藏类的引用。执行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黑客维亚切斯拉夫·叶戈罗夫):