Сегодня я прочитал эту ветку о скорости конкатенации строк.
Удивительно, но конкатенация строк оказалась победителем:
Результат оказался противоположным тому, что я думал. Кроме того, есть много статей по этому поводу , которые объясняют , как противно это .
Я могу предположить, что браузеры оптимизированы для работы с строками concat
в последней версии, но как они это делают? Можно ли сказать, что лучше использовать +
при конкатенации строк?
Обновить
Таким образом, в современных браузерах конкатенация строк оптимизирована, поэтому использование +
знаков выполняется быстрее, чем использование, join
когда вы хотите объединить строки.
Но @Arthur указал, что join
это быстрее, если вы действительно хотите объединить строки с разделителем.
Обновление - 2020
Chrome: массив join
почти 2 times faster
равен String concat +
См .: https://stackoverflow.com/a/54970240/984471
В качестве примечания:
- Массив
join
лучше, если у вас естьlarge strings
- Если нам нужно сгенерировать
several small strings
в окончательном выводе, лучше использовать конкатенацию строк+
, так как в противном случае для использования массива потребуется несколько преобразований массива в строку в конце, что является перегрузкой производительности.
источник
Ответы:
Механизм JavaScript V8 (используемый в Google Chrome) использует этот код для объединения строк:
Итак, внутренне они оптимизируют его, создавая InternalArray (
parts
переменную), которая затем заполняется. С этими частями вызывается функция StringBuilderConcat. Это быстро, потому что функция StringBuilderConcat представляет собой сильно оптимизированный код C ++. Здесь слишком долго цитировать, но найдите код в файле runtime.ccRUNTIME_FUNCTION(MaybeObject*, Runtime_StringBuilderConcat)
.источник
arr.join vs str+
на chrome вы получите (в операциях в секунду)25k/s vs 52k/s
. на firefox новый вы получаете76k/s vs 212k/s
. такstr+
БЫСТРЕЕ. но давайте посмотрим другие браузеры. Opera выдает 43 к / с против 26 к / с. IE дает1300/s vs 1002/s
. посмотреть, что происходит? только браузер, оптимизация НЕОБХОДИМОСТЬ будет лучше использовать то , что происходит медленнее всех остальных, где это не имеет значения. Итак, ни одна из этих статей ничего не понимает о производительности.Firefox быстр, потому что он использует нечто, называемое веревками ( веревки: альтернатива строкам ). Веревка - это, по сути, просто DAG, где каждый узел представляет собой строку.
Так, например, если вы это сделаете
a = 'abc'.concat('def')
, вновь созданный объект будет выглядеть так. Конечно, это не совсем то, как это выглядит в памяти, потому что вам все равно нужно иметь поле для типа строки, длины и, возможно, другого.И
b = a.concat('123')
Так что в простейшем случае виртуальная машина почти не выполняет никакой работы. Единственная проблема в том, что это немного замедляет другие операции с результирующей строкой. Кроме того, это, конечно, снижает накладные расходы на память.
С другой стороны
['abc', 'def'].join('')
, обычно просто выделяет память, чтобы разместить новую строку в памяти. (Возможно, это стоит оптимизировать)источник
Я знаю, что это старая ветка, но ваш тест неверен. Вы делаете,
output += myarray[i];
пока это должно быть больше похоже на то,output += "" + myarray[i];
что вы забыли, что вам нужно чем-то склеивать предметы. Код concat должен быть примерно таким:Таким образом, вы выполняете две операции вместо одной из-за склеивания элементов вместе.
Array.join()
быстрее.источник
"" +
и оригиналом?output
без него.Array.join(",")
что не будет работать с вашимfor
цикломПри большом объеме данных соединение происходит быстрее, поэтому вопрос сформулирован неверно.
Проверено в Chrome 72.0.3626.119, Firefox 65.0.1, Edge 42.17134.1.0. Обратите внимание, что это быстрее даже с включенным созданием массива!
источник
Тесты там тривиальны. Повторное объединение одних и тех же трех элементов будет встроено, результаты будут детерминированы и запомнены, обработчик мусора будет просто выбрасывать объекты массива (которые будут почти нулевыми по размеру) и, вероятно, просто выталкиваются и выталкиваются из стека из-за отсутствия внешние ссылки и потому, что строки никогда не меняются. Я был бы более впечатлен, если бы в тесте было большое количество случайно сгенерированных строк. Как в одном или двух концертах.
Array.join FTW!
источник
Я бы сказал, что со строками легче предварительно выделить больший буфер. Каждый элемент имеет размер всего 2 байта (если используется UNICODE), поэтому, даже если вы консервативны, вы можете предварительно выделить довольно большой буфер для строки. С
arrays
каждым элементом все более «сложно», потому что каждый элемент является однимObject
, поэтому консервативная реализация будет предварительно выделять пространство для меньшего количества элементов.Если вы попытаетесь добавить
for(j=0;j<1000;j++)
перед каждым,for
вы увидите, что (под хромом) разница в скорости становится меньше. В конце концов, конкатенация строк все еще была в 1,5 раза, но меньше, чем было до 2,6.И при необходимости копировать элементы, символ Unicode, вероятно, меньше, чем ссылка на объект JS.
Имейте в виду, что существует вероятность того, что многие реализации JS-движков имеют оптимизацию для однотипных массивов, что сделает все, что я написал, бесполезным :-)
источник
Этот тест показывает, что фактическое использование строки, созданной с помощью конкатенации присваиваний, по сравнению с методом array.join, не оправдано. Хотя общая скорость присваивания по-прежнему в два раза выше в Chrome v31, но она уже не так велика, как без использования результирующей строки.
источник
Это явно зависит от реализации движка javascript. Даже для разных версий одного движка можно получить существенно разные результаты. Вы должны провести собственный тест, чтобы убедиться в этом.
Я бы сказал, что он
String.concat
имеет лучшую производительность в последних версиях V8. Но для Firefox и OperaArray.join
это победитель.источник
Я предполагаю, что, хотя каждая версия требует многих конкатенаций, версии соединения создают массивы в дополнение к этому.
источник