基准:http://jsperf.com/substringing http://jsperf.com/substringing
因此,我正在启动我的第一个基于 HTML5 浏览器的客户端项目。本质上,它必须将非常非常大的文本文件解析为一个或多个对象数组。我知道我将如何编码;我现在最关心的是尽快获得解析器代码,我的主要测试平台是 Chrome。然而,在查看子字符串方法之间的差异时(我已经很长一段时间没有接触过 JavaScript),我注意到与 FireFox 相比,Chrome 中的这个基准测试速度慢得令人难以置信。为什么?
我的第一个假设是,它与 FireFox 的 JS 引擎处理字符串对象的方式有关,对于 FireFox 来说,这个操作是简单的指针操作,而对于 Chrome 来说,它实际上是在进行硬拷贝。但是,我不知道为什么 Chromewouldn't进行指针操作或者为什么使用 FireFoxwould。有人有一些见解吗?
JSPerf 似乎丢弃了我的 FireFox 结果,而不是在 BrowserScope 上显示它们。对我来说,每秒执行次数为 9,568,203 ±1.44%.substr()
in FF4.
编辑:所以我看到 FF3.5 的性能结果实际上低于 Chrome。所以我决定检验我的指针假设。这让我想到了一个第二次修订 http://jsperf.com/substringing/2我的子字符串测试,正在做1,092,718±1.62%
FF4 中的每秒操作数与1,195±3.81%
Chrome 中的 Ops/sec,仅快了 1000 倍,但性能仍然存在难以解释的差异。
后记:不,我对 Internet Explorer 一点也不关心。我很关心如何提高自己的技能并更深入地了解这门语言。
以 Spidermonkey(Firefox 中的 JS 引擎)为例,substring()
调用只是创建一个新的“依赖字符串”:一个字符串对象,它存储指向子字符串的指针以及开始和结束偏移量。这正是为了让substring()
速度快,并且对于不可变字符串来说是一个明显的优化。
至于为什么 V8 不这样做...一种可能是 V8 试图节省空间:在依赖字符串设置中,如果您保留子字符串但忘记原始字符串,则原始字符串无法被 GC 处理,因为子字符串正在使用其字符串数据的一部分。
无论如何,我只是查看了 V8 源代码,看起来他们根本不执行任何类型的依赖字符串;评论没有解释why但他们不这样做。
[更新,12/2013]:在我给出上述答案几个月后,V8 添加了对依赖字符串的支持,正如 Paul Draper 指出的那样。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)