2013-07-24 31 views
11

我读过一些关于V8隐藏类的文章。不过,我仍然有我的头几个问题:清除V8的隐藏类概念

如果,比方说,有两个对象:

var a = { } 
a.x = 5 
a.y = 6 

var b = { } 
b.y = 7 
b.x = 8 

难道他们结束了同一个隐藏类或分开只是因为一个人去0 + x + y和另一个0 + y + x?据我了解,他们得到不同的班,但只是想确保我得到了它。

然后,我们有这样的情况:

function Point(x, y) { 
    this.x = x 
    this.y = y 
} 
var a = new Point(7, 8) 

var b = { } 
b.x = 6 
b.y = 8 

var c = { 
    x: 8, 
    y: 9 
} 

var d = { 
    y: 9, 
    x: 80 
} 

难道我们结束了同一个隐藏类?我可能猜到a,bc做但d没有。除非在这样的对象表达式上进行了一些排序(类似于针对该类型分析的数组的短声明)。

最后,我们有这样的:

function PointA(x, y) { 
    this.x = x 
    this.y = y 
} 
var a = new PointA(7, 8) 

function PointB(x, y) { 
    this.x = x 
    this.y = y 
} 
var b = new PointB(7, 8) 

是八九不离十类似第二种情况。除了它们的来源(instanceof...)不同之外,这些对象似乎相同。但是,那里的对象最终是否有相同的隐藏类?

+1

Javascript没有课程。隐藏的类不是概念,它们是实现的内部细节。除非你想破解v8或其他需要解决类似问题的虚拟机,否则你并不在意。 –

+3

我其实关心我写的代码的性能。我经历过我自己,当你走的时候关心表现*而不是在有人抱怨跑步速度太慢时关心它会更简单。 – Pijusn

+0

有些方面的表现,你确实需要关心,因为你去。就像选择最佳算法一样,缓存你经常需要的数据等等。但是如果你真的需要关心这个级别的性能,那么你不应该首先使用JavaScript。 –

回答

14

如果您下载V8并构建调试版本,您可以随机将这些对象传递给无限循环中的函数,并打印出优化的反汇编代码,并查看它们是否被视为具有相同的类。

在第一种情况下,你是对的,他们会有不同的隐藏类。


在第二种情况下,你错了,你最终会得到4个不同的类,所以他们都没有共享一个类。首先,添加到构造函数或对象文本外的对象的字段不会直接存储在对象上,而是存储在对象外部的数组中。所以这就是为什么b将有不同于每个人的隐藏课程。

一个独特的构造函数将构造唯一类的对象,因此a将有不同于每个人的隐藏类。对象 文字具有与第一种情况相同的不同顺序的属性。

但是反对文字完全相同的布局将共享一个隐藏的类,所以如果我们添加的对象e

var e = { 
    x: 32, 
    y: -15 
}; 

然后c将与e共享同一个隐藏的类。


在第三情况下,它们将具有不同的隐藏的类相同的理由,在第二种情况下,唯一的构造 构造不同类的对象。


您也可能会发现这个有趣的https://codereview.stackexchange.com/a/28360/9258

+0

有**相同的隐藏类**有什么大不了?你能解释一下吗? – TrungDQ

+1

这完全是关于性能的,因为优化器根据需要支持哪些隐藏类来不同地处理代码网站。例如,如果在特定的代码行中,某个特定的参数总是具有相同的隐藏类,则该调用可以被认为是单形的,这允许[更积极的内联缓存](http://en.wikipedia.org/wiki/Inline_caching#Monomorphic_inline_caching)和其他优化策略。 – Domi

5

您可以轻松地通过使用V8的调试外壳d8检查。

// test1.js 
var a = { } 
a.x = 5 
a.y = 6 

var b = { } 
b.y = 7 
b.x = 8 

print(%HaveSameMap(a, b)); 

然后运行

$ d8 --allow-natives-syntax test1.js 

你会得到预期的输出:

false 

对于你第二个例子:

//test2.js 
function Point(x, y) { 
    this.x = x 
    this.y = y 
} 

var a = new Point(7, 8) 

var b = { } 
b.x = 6 
b.y = 8 

var c = { 
    x: 8, 
    y: 9 
} 

var d = { 
    y: 9, 
    x: 80 
} 

print(%HaveSameMap(a, b)); 
print(%HaveSameMap(b, c)); 
print(%HaveSameMap(b, d)); 
print(%HaveSameMap(c, d)); 

所有4个对象有不同的隐藏类:

$ d8 --allow-natives-syntax test2.js 
false 
false 
false 
false 

最后但并非最不重要的:

// test3.js 
function PointA(x, y) { 
    this.x = x 
    this.y = y 
} 
var a = new PointA(7, 8) 

function PointB(x, y) { 
    this.x = x 
    this.y = y 
} 
var b = new PointB(7, 8) 
var c = new PointB(1,4) 

print(%HaveSameMap(a, b)); 
print(%HaveSameMap(b, c)); 

ab有不同的隐藏的类,但bc相同。

$ d8 --allow-natives-syntax test3.js 
false 
true