Javascript子字符串是虚拟的吗?

Posted

技术标签:

【中文标题】Javascript子字符串是虚拟的吗?【英文标题】:Is Javascript substring virtual? 【发布时间】:2013-12-30 11:03:04 【问题描述】:

如果我们有一个巨大的字符串,命名为str1,假设有 500 万个字符长,然后是str2 = str1.substr(5555, 100),那么str2 的长度是 100 个字符,并且是 str1 的子字符串,从 5555(或任何其他随机选择的位置)。

javascript 如何在内部存储str2?是复制了字符串内容还是新字符串是虚拟的,并且只存储了对原始字符串的引用以及位置和大小的值?

我知道这取决于实现,ECMAScript 标准(可能)没有定义字符串实现的底层内容。但我想从内部了解 V8 或 SpiderMonkey 的专家那里了解这一点。

谢谢

【问题讨论】:

blog.mozilla.org/javascript/2014/07/21/… 【参考方案1】:

AFAIK V8 有四种字符串表示:

    ASCII UTF-16 多个字符串的串联 另一个字符串的切片

因此,它不必复制字符串;它只需要开始和结束标记到另一个字符串。

SpiderMonkey 做同样的事情。 (请参阅Large substrings ~9000x faster in Firefox than Chrome: why? ... 虽然 Chrome 的答案已经过时。)

这可以真正提高速度,但有时这是不可取的,因为它会导致小字符串占用较大父字符串的内存 (V8 bug report)

【讨论】:

【参考方案2】:

我的这篇旧博文解释了它,以及其他一些字符串表示形式:http://blog.cdleary.com/2012/01/string-representation-in-spidermonkey/

搜索“依赖字符串”。我想我知道您可能会遇到这个问题:有时它们可​​能是有问题的,因为 if 没有对原始内容的引用,您可以保留一个巨大的字符串以便保留一个实际上在语义上可达的小子字符串。实现可以做一些事情来缓解这个问题,比如在 GC 生成的基础上记录信息,以查看是否存在这样的依赖字符串实体并将它们折叠到最小大小,但最后我知道这不是完毕。 (基本上使用这种方法,您可以在 GC 扫描时恢复 runtime_refcount == 1 样式信息。)

【讨论】:

【参考方案3】:

字符串是immutable,对它们的任何操作都会创建新的字符串。 str2 是一个全新的字符串,包含从 str1 复制的数据。

【讨论】:

由于切片部分也是不可变的,因此您不需要复制数据,因为用户无法尝试更改它。此外,即使在可变字符串的情况下,理论上也可以使用写时复制方法,将实际复制延迟到何时(以及是否)完成更改。

以上是关于Javascript子字符串是虚拟的吗?的主要内容,如果未能解决你的问题,请参考以下文章

如何检查字符串是不是包含 JavaScript 中的子字符串?

如何检查字符串是不是包含 JavaScript 中的子字符串?

如何检查字符串是不是包含 JavaScript 中的子字符串?

如何检查字符串是不是包含 JavaScript 中的子字符串?

如何检查字符串是不是包含 JavaScript 预定义数组中存在的子字符串?

javascript子字符串