2013-09-27 61 views
12

所以这是一个有趣的一个......当我测试setAttribute与一个元素上的普通属性集的性能时,我发现了一个奇怪的行为,然后在普通物体上进行测试......并且还是很奇怪!Chrome的性能:“标准”属性名称与非标准

所以,如果你有一个对象A = {}, 并设置其属性像A['abc_def'] = 1,或A.abc_def = 1,他们基本上是相同的。 但是,如果你做A['abc-def'] = 1或A['123-def'] = 1,那么你有麻烦了。它走得慢一些。 我在这里设置了一个测试:http://jsfiddle.net/naPYL/1/。除了Chrome以外,它们在所有浏览器上的工作都一样。 有趣的是,对于“abc_def”属性,chrome实际上比Firefox和IE快得多,正如我所料。但对于“abc-def”来说,它至少要慢两倍。

所以基本上(至少从我的测试)这里发生的是,当使用“正确”语法的属性(合法的C语法,你可以使用点属性) - 速度很快,但是当你使用需要的语法使用括号(a [...]),那么你有麻烦了。

我试图想象在两种模式之间以何种方式区分实现细节,而不能。因为我认为,如果你确实支持那些非标准的名字,你可能会把所有的名字翻译成相同的机制,其余的只是编译到这个机制中的语法。所以。语法和[]在编译后应该完全相同。但显然这里有一些其他的方式......

没有看V8的源代码,任何人都可以想到一个真正令人满意的答案? (你可以把它作为一个练习:-))

Here's also a quick jsperf.com example

由于NDM为jsperf例子!

编辑:

为了澄清,我当然也想从实际代码 (我已经找到),或者更精确地说一个具体的答案 - 那 具体实施背后的原因。这就是我要求你以“练习”的形式看待它的原因之一,请看技术 的实现并试图找出原因。

但我也想看看其他人的思维如何在这些情况下工作。 这可能听起来对你们中的某些人来说“模糊” - 但它不时像其他人一样尝试并认为 非常有用,或者采取他们的观点。它 增强你自己的思维方式。

+4

令人惊叹的问题。 V8有一个支持类机制,它将尝试将标准C++类与对象配对以加快速度。实际上,它可能是 - 当语法不标准时,这种支持类无法建立,因此Chrome以标准方式处理属性(最有可能是散列表)。 – GameAlchemist

+1

我已经添加了一个jsperf测试并将其链接到您的问题中。 FYI在我的铬合金上慢了6%。在FF中他们同样快,但比Chrome更快7倍! – NDM

+1

我认为这个问题有可能会因为*而不是V8的源代码[*],认为它是一个练习。这是一个有趣的问题,但是这条线鼓励投机而不是具体的答案,而这通常是不被接受的。 –

回答

5

所以JS对象可以用于两个相冲突的目的。它们可以用作对象,但它们也可以用作散列表。然而,对于哈希表而言,对于对象而言,什么是快速且有意义的 并非如此,因此V8试图猜测给定对象是什么。

有些迹象表明用户可以给他想要的字典正在删除一个属性或giving a property a name that cannot be accessed using dot notation

也使用了其他一些启发式方法,我做了一个要点https://gist.github.com/petkaantonov/6327915

然而,有a really cool hack从哈希表地狱redempts对象:

function ensureFastProperties(obj) { 
    function f() {} 
    f.prototype = obj; 
    return obj; 
} 

看到它在行动:http://jsperf.com/property-dash-parformance/2

由于属性存储在外部属性数组中,而不是对象中,所以已兑换的对象不如原始对象快。但是这仍然比散列表好得多。请注意,这仍然是非常糟糕的基准测试,不要认为一秒钟散列表只比inobject属性慢两倍。

+0

酷的黑客似乎没有工作在'Chrome 30.0.1599.65 beta-m' – C5H8NNaO4

+0

@ C5H8NNaO4是需要调查..优化对象在原型分配中的代码仍然存在,即使在最流血的边缘v8 – Esailija