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

问题描述

| 基准测试:http://jsperf.com/substringing 因此,我正在启动我的第一个基于HTML5浏览器的客户端项目。实际上,它必须将非常大的文本文件解析为一个或多个对象数组。我知道我将如何编码。我现在最关心的是尽快获取解析器代码,而我的主要测试平台是Chrome。但是,在查看子字符串方法间的差异(很长一段时间以来我都没有接触过JavaScript)时,我注意到与FireFox相比,Chrome中的基准测试速度非常慢。为什么? 我的第一个假设是,它与FireFox的JS引擎处理字符串对象的方式有关,对于FireFox,此操作是简单的指针操作,而对于Chrome,它实际上是在进行硬拷贝。但是,我不确定Chrome为什么不执行指针操作或FireFox为什么会这样做。有人有见识吗? JSPerf似乎正在抛出我的FireFox结果,而不是将它们显示browserScope上。对我而言,在FF4中,ѭ0I获得9,568,203±1.44%Ops / sec。 编辑:所以我看到实际上在Chrome以下的FF3.5性能结果。因此,我决定检验我的指针假设。这使我进入了Substrings测试的第二次修订版,在FF4中每秒运行
1,092,718±1.62%
,而在Chrome中每秒运行Chrome2 doing,降速只有1000倍,但性能仍然存在无法解释的差异。 后记:不,我不关心Internet Explorer。我担心尝试提高自己的技能并更深入地了解这种语言。     

解决方法

        在Spidermonkey(Firefox中的JS引擎)的情况下,调用
substring()
只会创建一个新的\“ depending string \”:一个字符串对象,该指针存储一个指向该对象的指针,该指针是其子字符串关闭以及起始和结束偏移量。正是为了使
substring()
快速,并且对于不变的字符串,这是显而易见的优化。 至于为什么V8不能这样做...一种可能是V8试图节省空间:在从属字符串设置中,如果您坚持使用子字符串却忘记了原始字符串,则原始字符串将无法被GC,因为子字符串正在使用其一部分字符串数据。 无论如何,我只是看了V8源代码,看起来好像它们根本不做任何形式的依赖字符串。不过,这些评论并不能解释为什么不这样做。 [更新,12/2013]:正如Paul Draper指出的那样,在我给出上述答案的几个月后,V8增加了对依赖字符串的支持。     ,        您是否已从基准测试结果中消除了ѭ5的读数? 我相信V8有一些字符串表示形式:
1. a sequence of ASCII bytes
2. a sequence of UTF-16 code units.
3. a slice of a string (result of substring)
4. a concatenation of two strings.
数字4是使字符串
+=
高效的原因。 我只是猜测,但是如果他们试图将两个字符串指针和一个长度打包到一个很小的空间中,则它们可能无法使用指针缓存较大的长度,因此可能最终会按顺序遍历联接的链接列表计算长度。这当然假设assume8ѭ从数组部分创建形式为(4)的字符串。 确实导致了可检验的假设,该假设甚至可以解释即使没有缓冲区拷贝也存在差异。 编辑: 我浏览了V8源代码,然后我将开始使用StringBuilderConcat,尤其是
runtime.cc
。