Используют ли обычные реализации JavaScript интернирование строк?

Используют ли распространенные движки JavaScript, такие как V8 и JavaScriptCore WebKit, интернирование строк для строк JavaScript? Или они на самом деле хранят в памяти несколько экземпляров одинаковых строк?


person kpozin    schedule 11.03.2011    source источник


Ответы (3)


Да. Как правило, любая литеральная строка, идентификатор или другая постоянная строка в исходном коде JS интернируется. Однако детали реализации (например, что именно интернировано) различаются, а также когда происходит интернирование.

Обратите внимание, что строковое значение не совпадает со строковым объектом, хотя строковые объекты не интернируются, потому что это было бы принципиально неверным поведением.

person olliej    schedule 11.03.2011
comment
Привет, @olliej, есть ли источник твоего заявления? - person Felipe Sabino; 04.01.2012
comment
@FelipeSabino Учитывается ли работа над крупным движком и участие в комитете по ecmascript? ;) А если серьезно, вы можете посмотреть исходники JavaScriptCore, SpiderMonkey, V8 и т. д. в Интернете. - person olliej; 06.01.2012
comment
Конечно, я мог бы посмотреть любой открытый исходный код и проверить его самостоятельно, но одна из причин, по которой существует SO, заключается в том, чтобы избежать этих хлопот, смеется. Вопрос не в том, чтобы сомневаться в своих знаниях, а в том, чтобы помочь разработчикам в их исследованиях. Кажется, вы тот, кто много знает об этом предмете, а также имеете гораздо более подробные ссылки, которые могли бы помочь мне узнать намного больше об этом предмете. Просто в качестве примера вы сказали, что в целом строки интернированы, в каких случаях это не так? и так далее... - person Felipe Sabino; 17.01.2012
comment
@FelipeSabino логика стажировки (по крайней мере, в АО) распространяется на несколько областей. Однако базовая модель аналогична Java: строки-константы интернируются автоматически, а результаты конкатенации строк и т. д. — нет. В Java вы можете явно принудительно интернировать, но этого не существует в JS. - person olliej; 03.02.2012
comment
@olliej Не могли бы вы посмотреть здесь - идет острая дискуссия stackoverflow.com/questions/26549715/ также здесь stackoverflow.com/questions/26532550/. Спасибо! Помощь очень ценится :) - person Michail Michailidis; 24.10.2014

http://jsperf.com/strinterning

Да в Хроме, нет в Авроре 15 и ФФ 13! Сравнение двух строк на 85% медленнее, чем сравнение двух указателей в Firefox. Однако в Chrome такая же скорость, что указывает на то, что он сравнивает два указателя.

Может быть, команде разработчиков JS в Mozilla следует проверить свой код...

person Norman Pellet    schedule 04.07.2012
comment
Если вы думаете, что это плохо, IE9 даже не сравнивает указатели при сравнении строковой переменной с самой собой. (Связанные JSPerfs.) - person kpozin; 09.07.2012

Краткий ответ: иногда да, иногда нет.

Я также наткнулся на тот же вопрос и немного изучил его. Кажется, что интернирование обычно выполняется для строковых литералов, которые генерируются одинаково (например, всегда присваивают одну и ту же строку переменной в одном и том же цикле), НО я также смог создать пример, который приводит к созданию двух идентичных строк. с двумя разными ссылками:

Снимок кучи инструментов Chrome dev, показывающий пары идентичных строковых значений с разными идентификаторами ссылки

Как видите, каждая строка хранится дважды, имея разные ссылки.

Это код, который я использовал для создания повторяющихся строк:

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

Кажется, что интернирование строк выполняется для строковых литералов, но не для конкатенированных строковых значений, но, как вы можете видеть выше, каждая конкатенированная строка появляется только дважды, а не 100x2 = 200 раз, поэтому интернирование строк все еще выполняется для конкатенированных строк, созданных в внешняя петля.

person XCS    schedule 31.10.2018
comment
что это за консоль? Я не могу заставить стрелки слева появляться на строках или, что более любопытно, ссылку в сером цвете справа на Opera/Chrome/Firefox - person towc; 08.02.2019
comment
@towc Это снимок кучи памяти из инструментов разработчика Chrome. - person XCS; 08.02.2019
comment
@XCS Я не думаю, что это правильно: интернирование строк все еще выполняется для конкатенированных строк, созданных во внешнем цикле. Вы не поддерживаете ссылки на строки, созданные в более ранних итерациях внешнего цикла (каждую итерацию вы перезаписываете каждый элемент a и b), но В моментальные снимки включаются только достижимые объекты. Если вы сохраняет ссылки на ранее объединенные строки, тогда вы получите 200 копий каждой строки. - person Han Seoul-Oh; 20.05.2021
comment
@ HanSeoul-Oh Итак, объединенные строки никогда не интернируются? - person XCS; 21.05.2021
comment
@XCS К сожалению, я понятия не имею, поэтому я гуглил и наткнулся на этот вопрос! :) Единственное, в чем я уверен, это то, что ваш тестовый пример не иллюстрирует ситуацию, когда конкатенированные строки интернируются, вместо этого он показывает, что моментальные снимки кучи не включают недостижимые объекты. Однако могут быть и другие ситуации, когда конкатенированные строки интернированы, и я понятия не имею, как их найти или доказать, что они не существуют. - person Han Seoul-Oh; 22.05.2021
comment
@ HanSeoul-О, я не думаю, что вы можете доказать, что чего-то не существует, единственный способ - узнать, как работает V8 внутри (или какой-либо другой JS-движок, для которого мы это тестируем). - person XCS; 22.05.2021