Do common JavaScript implementations use string interning?
Asked Answered
W

3

54

Do common JavaScript engines, such as V8 and WebKit's JavaScriptCore, use string interning for JavaScript strings? Or do they actually keep multiple instances of identical strings in memory?

Whitver answered 11/3, 2011 at 18:34 Comment(0)
S
41

Yes. In general any literal string, identifier, or other constant string in JS source is interned. However implementation details (exactly what is interned for instance) varies, as well as when the interning occurs.

Note that a string value is not the same as a String Object though, String Objects are not interned because that would be fundamentally incorrect behaviour.

Sabbatical answered 11/3, 2011 at 18:40 Comment(5)
Hi @olliej, is there any source for your statement?Favouritism
@FelipeSabino Does working on a major engine and being on the ecmascript committee count? ;) More seriously though you can look at the sources for JavaScriptCore, SpiderMonkey, V8, etc online.Sabbatical
Of course I could look at any open source code and check it for myself, but one of the reasons SO exists is to avoid this hassle, lol. It is not a question of doubting your knowledge, it is only a concern about helping developers with their research. It seems that you are someone that knows a lot about the subject, and also with much more thrustful references that could help me to learn a lot more about this subject. Just exemplifying, you said "in general strings are interned", what are the cases where they are not? and so on...Favouritism
@FelipeSabino the logic for interning (at least in JSC) is spread over multiple areas. The basic model is similar to Java though -- constant strings are interned automatically, results of string concatenation, etc aren't. In Java you can explicitly force interning but that doesn't exist in JS.Sabbatical
@Sabbatical Could you please have a look on here - there is a strong debate #26550215 also on here #26533050. Thanks! Help is really appreciated :)Dupuis
P
14

http://jsperf.com/strinterning

Yes in Chrome, no in Aurora 15 and FF 13! Comparing two strings is 85% slower than comparing two pointers in Firefox. However it's the same speed in Chrome, which is an indication that it is comparing two pointers.

Maybe the JS engine team at Mozilla should check their code...

Povertystricken answered 4/7, 2012 at 19:2 Comment(2)
If you think that's bad, IE9 doesn't even do pointer comparisons when comparing a string variable to itself. (Related JSPerfs.)Whitver
the links are dead.Nabonidus
M
5

Short answer: sometimes yes, sometimes no.

I also stumbled upon the same question and looked a bit into it. It seems that interning is done usually for string literals that are generated the same way (eg. always assigning the same string to a variable in the same loop), BUT I was also able to create an example which results in two identical strings being created with two different references:

Chrome dev tools heap snapshot showing pairs of identical string values with different reference IDs

As you can see, each string is stored twice, having different references.

This is the code I used to generate the duplicate strings:

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;
}

It seems that string interning is done for string literals, but not for concatenated string values, but as you can see above, each concatenated string only appears twice, not 100x2 = 200 times, so there is still string interning done for concatenated strings created in the outer loop.

Maddi answered 31/10, 2018 at 11:9 Comment(6)
what console is this? I can't get the arrows on the left to happen on strings, or more curiously the reference in grey on the right on opera/chrome/firefoxSubdivision
@Subdivision It's a memory heap snapshot from chrome dev tools.Maddi
@Maddi I don't think this is right: "there is still string interning done for concatenated strings created in the outer loop". You aren't maintaining references to the strings created in earlier iterations of the outer loop (every iteration you overwrite every element of a and b), but "Only reachable objects are included in snapshots." If you maintain references to the earlier concatenated strings, then you do get 200 copies of each string.Petrina
@HanSeoul-Oh So concatenated strings are never interned?Maddi
@Maddi I have no idea, unfortunately, that's why I was googling around and came upon this question! :) The only thing I'm sure of is that your test case does not illustrate a situation where concatenated strings are being interned, instead it illustrates that heap snapshots don't include unreachable objects. However, there may be other situations where concatenated strings are interned, and I have no idea how to find one or prove they don't exist.Petrina
@HanSeoul-Oh I don't think you can prove something doesn't exist, the only way would be to know how V8 works internally (or whatever JS engine we're testing this for).Maddi

© 2022 - 2024 — McMap. All rights reserved.