所以这是一个有趣的...当我在一个元素上测试setAttribute与普通属性设置的性能时,我发现了一个奇怪的行为,然后我在常规对象上进行了测试......它仍然很奇怪!
所以如果你有一个对象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
感谢jsperf示例的NDM!
修改
为了澄清,我当然也希望从实际代码中得到具体答案 (我已经找到了)或更确切地说 - 背后的原因 具体实施。这是我要你的原因之一 把它看作“锻炼”,看看技术背后 实施并试图找到原因。
但我也希望看到其他人的思想如何在这样的情况下发挥作用。 对于你们中的一些人来说这可能听起来“模糊” - 但尝试和思考是非常有用的 像其他人不时,或采取他们的观点。它 增强自己的思维方式。
答案 0 :(得分: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会从哈希表地狱中兑换一个对象:
function ensureFastProperties(obj) {
function f() {}
f.prototype = obj;
return obj;
}
查看实际操作:http://jsperf.com/property-dash-parformance/2。
兑换的对象没有原始对象快,因为属性存储在外部属性数组中而不是对象中。但这仍然比哈希表好得多。请注意,这仍然是相当破碎的基准测试,不要认为哈希表只比inobject属性慢2倍。