大型子串在Firefox中比Chrome快9000倍:为什么?

Mis*_*Nix 19 javascript performance firefox google-chrome jsperf

基准:http://jsperf.com/substringing

所以,我正在启动我的第一个基于HTML5浏览器的客户端项目.它必须将非常非常大的文本文件解析成一个或多个对象的数组.我知道我将如何编码呢; 我现在主要关注的是尽可能快地获取解析器代码,而我的主要测试平台是Chrome.然而,在查看子串方法之间的差异时(我很长时间没有触及过JavaScript),我注意到与FireFox相比,Chrome中的这个基准测试速度非常慢.为什么?

我的第一个假设是,它与FireFox的JS引擎处理字符串对象的方式有关,而对于FireFox,这个操作是简单的指针操作,而对于Chrome,它实际上是做硬拷贝.但是,我不确定为什么Chrome 不会做指针操作或为什么FireFox .有人有见识吗?

JSPerf似乎丢弃了我的FireFox结果,而不是在BrowserScope上显示它们.对我来说,我.substr()在FF4中获得了9,568,203±1.44%Ops/sec .

编辑:所以我在Chrome下面看到了FF3.5的性能结果.所以我决定测试我的指针假设.这让我进入了我的Substrings测试的第二次修订,它1,092,718±1.62%在FF4中的1,195±3.81%Ops /秒与Chrome中的Ops/sec 相比,速度提高了不到1000倍,但仍然是性能上无法解释的差异.

后记: 不,我不关心舔一下Internet Explorer.我很关心尝试提高自己的技能,并在更深层次上了解这种语言.

Bor*_*sky 15

在Spidermonkey(Firefox中的JS引擎)的情况下,substring()调用只是创建一个新的"依赖字符串":一个字符串对象,它存储指向它的子字符串的指针以及开始和结束偏移.这恰恰是为了substring()快速,并且是一个明显的优化给定不可变的字符串.

至于为什么V8不这样做......可能是V8试图节省空间:在依赖字符串设置中如果你坚持子字符串却忘记了原始字符串,原始字符串就无法获得GCed,因为substring使用其字符串数据的一部分.

在任何情况下,我只看了V8源代码,看起来他们根本就没有做任何类型的依赖字符串; 但评论并没有解释为什么他们不这样做.

[更新,2013年12月]:在我给出上述答案后几个月,V8增加了对依赖字符串的支持,正如Paul Draper指出的那样.