常见的JavaScript实现是否使用字符串实习?

kpo*_*zin 33 javascript programming-languages webkit v8 string-interning

常见的JavaScript引擎(如V8和WebKit的JavaScriptCore)是否使用字符串实习来处理JavaScript字符串?或者他们实际上在内存中保留了多个相同字符串的实例?

oll*_*iej 24

是.通常,JS源中的任何文字字符串,标识符或其他常量字符串都是实体.然而,实施细节(例如,实际上是实施的内容)会有所不同,以及实施时的实施情况.

请注意,字符串值与字符串对象不同,但字符串对象不会被中断,因为这基本上是不正确的行为.

  • 当然,我可以查看任何开源代码并自行检查,但SO存在的原因之一是避免这种麻烦,哈哈.这不是怀疑你的知识的问题,只是关心帮助开发人员进行研究.看来你是一个对这个主题有很多了解的人,而且还有更多有用的参考资料可以帮助我更多地了解这个主题.举个例子,你说"一般来说字符串是实习的",它们不是什么情况?等等... (8认同)
  • @FelipeSabino实习的逻辑(至少在JSC中)分布在多个领域.基本模型类似于Java - 常量字符串是自动实现的,字符串连接的结果不是.在Java中,您可以明确强制实习,但JS中不存在. (5认同)
  • @FelipeSabino是否在主要引擎上工作并参加ecmascript委员会计算?;)更严肃的是,你可以在线查看JavaScriptCore,SpiderMonkey,V8等的来源. (4认同)
  • 您好@olliej,您的陈述是否有任何来源? (3认同)

小智 10

http://jsperf.com/strinterning

在Chrome中是,在Aurora 15和FF 13中没有!比较两个字符串比在Firefox中比较两个指针要慢85%.然而,它在Chrome中的速度相同,这表明它正在比较两个指针.

也许Mozilla的JS引擎团队应该检查他们的代码......

  • 如果您认为这很糟糕,IE9甚至不会进行指针比较[比较字符串变量与*本身*](http://www.kpozin.net/archive/2011/05/ie9-and-string-equality) .([相关JSPerfs](http://jsperf.com/string-comparison1/3).) (4认同)

Cri*_*sty 5

简短回答:有时是,有时不是。

我也偶然发现了同样的问题,并仔细研究了一下。似乎实习通常是针对以相同方式生成的字符串文字完成的(例如,始终将相同的字符串分配给同一循环中的变量),但我也能够创建一个示例,该示例导致创建两个相同的字符串有两个不同的参考:

Chrome 开发工具堆快照显示具有不同引用 ID 的相同字符串值对

如您所见,每个字符串存储两次,具有不同的引用。

这是我用来生成重复字符串的代码:

const a = [];
const b = [];

for(let j  =1; j<= 100;++j){
    for(let i = 1; i <= 10000; ++i) a[i] = 'player 1 got 5 points from player 2' + i;
    for(let i = 1; i <= 10000; ++i) b[i] = 'player 1 got 5 points from player 2' + i;
}
Run Code Online (Sandbox Code Playgroud)

似乎字符串实习是针对字符串文字完成的,但不是针对连接的字符串值完成的,但正如您在上面看到的,每个连接的字符串只出现两次,而不是 100x2 = 200 次,因此仍然对在外循环。

  • @XCS我认为这是不对的:“对于在外循环中创建的连接字符串仍然进行了字符串实习”。您不会维护对外部循环早期迭代中创建的字符串的引用(每次迭代都会覆盖“a”和“b”的每个元素),但是[“快照中仅包含可访问的对象。”](https: //developer.chrome.com/docs/devtools/memory-problems/heap-snapshots/) 如果您[维护对早期连接字符串的引用](https://output.jsbin.com/fuwibuk),那么您[做获取每个字符串的 200 个副本](https://i.stack.imgur.com/nRRyd.png)。 (2认同)