Оператор + менее эффективен, чем StringBuffer.append ()

В моей команде мы обычно выполняем конкатенацию строк следующим образом:

var url = // some dynamically generated URL
var sb = new StringBuffer();
sb.append("<a href='").append(url).append("'>click here</a>");

Очевидно, что гораздо удобнее читать следующее:

var url = // some dynamically generated URL
var sb = "<a href='" + url + "'>click here</a>";

Но эксперты JS утверждают, что оператор + менее производительный, чем StringBuffer.append(). Это правда?

В javascript нет StringBuffer

Tomas 12.05.2010 15:43

Дон, ты имел в виду Java?

James McMahon 14.07.2010 19:24

По моему опыту, [].join('') показал действительно странное поведение, поэтому я вернулся к +: - /

martyglaubitz 19.03.2012 04:27

Я знаю, что основной вопрос здесь связан с конкатенацией строк, но вы должны проявлять осторожность при создании таких html-элементов. Ваш пример может сломаться, если url содержит ' или \n.

styfle 25.07.2013 00:24

Возможный дубликат Самый эффективный способ объединения строк в JavaScript?

Ciro Santilli TRUMP BAN IS BAD 13.10.2019 01:57

Интересно, почему этот вопрос не был закрыт из-за отсутствия ясности. Вместо этого он получил 91 голос за. В JS нет StringBuffer, так почему это вообще правильный вопрос?

Omkar76 28.10.2020 14:31
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
91
6
196 841
13
Перейти к ответу Данный вопрос помечен как решенный

Ответы 13

Да, это правда, но тебе все равно. Выбирайте тот, который легче читать. Если вам нужно протестировать свое приложение, сосредоточьтесь на узких местах.

Я предполагаю, что конкатенация строк не будет вашим узким местом.

Попробуй это:

var s = ["<a href='", url, "'>click here</a>"].join("");

Что ж, сообщение, на которое вы ссылаетесь в своем ответе, специально пытается опровергнуть «миф» о Array.join, о котором говорит мой ответ. Так что, возможно, нет. Я просто опубликовал то, что видел быстрее на практике.

Rahul 22.09.2008 01:49

люблю этот метод конкатенации строк.

bkwdesign 11.03.2014 21:47

В JavaScript нет собственного объекта StringBuffer, поэтому я предполагаю, что это из библиотеки, которую вы используете, или из функции необычной среды хоста (то есть не из браузера).

Я сомневаюсь, что библиотека (написанная на JS) могла бы производить что-либо быстрее, хотя собственный объект StringBuffer мог бы. Окончательный ответ можно найти с помощью профилировщика (если вы работаете в браузере, Firebug предоставит вам профилировщик для движка JS из Firefox).

По словам Кнута, «преждевременная оптимизация - корень всех зол!» Небольшое отклонение в любом случае, скорее всего, не будет иметь большого эффекта в конце; Я бы выбрал более читаемый.

Традиционно StringBuffer используется вместо конкатенации, потому что первый имеет временную сложность O (N), тогда как второй - O (N ^ 2), поэтому разница значительна для больших N (но не для малых N). В любом случае сценарий O (N ^ 2) может не выполняться в JavaScript в зависимости от используемой среды.

redcalx 30.08.2011 15:20

Да, по обычным тестам. Напр .: http://mckoss.com/jscript/SpeedTrial.htm.

Но для маленьких струн это не имеет значения. Вы будете заботиться только о выступлениях на очень больших струнах. Более того, в большинстве сценариев JS узкое место редко связано с манипуляциями со строками, поскольку их недостаточно.

Вам лучше понаблюдать за манипуляциями с DOM.

Ссылка мертвая .. https://web.archive.org/web/20150912072015/http://mckoss.com‌ /jscript/SpeedTrial.‌ htm указывает на версию веб-архива.

Tony 27.07.2018 13:26

Ваш пример не очень удачный, поскольку маловероятно, что производительность будет существенно отличаться. В вашем примере удобочитаемость должна превосходить производительность, потому что прирост производительности одного по сравнению с другим незначителен. Преимущества массива (StringBuffer) очевидны только тогда, когда вы выполняете много объединений. Даже тогда ваш пробег может сильно зависеть от вашего браузера.

Вот подробный анализ производительности, который показывает производительность с использованием всех различных методов конкатенации JavaScript во многих разных браузерах; Производительность строки и анализ

join() once, concat() once, join() for, += for, concat() for

Подробнее:
Ajaxian >> Производительность строки в IE: Array.join vs + = продолжение

Что касается графика, если он не очевиден; ниже - лучше.

Teekin 16.09.2010 00:37

«Перво-наперво с улучшением производительности в IE7, нам больше не нужно рассматривать использование альтернативного пути при выполнении крупномасштабных строковых операций; использование Array.join в итеративной ситуации не дает вам серьезных преимуществ, чем использование + = в той же ситуации. Кроме того, отличия от IE6 были достаточно небольшими, чтобы вы не беспокоились о разветвлении для этой конкретной версии ».

Chris S 11.01.2011 14:08

@ Крис, это неправда. Сравните эти две скрипки в IE7: jsfiddle.net/9uS4n/5 (быстро) против jsfiddle.net/9uS4n/2 (медленно). Похоже, что при использовании технологии join() производительность улучшается как минимум в 1000 раз.

Kirk Woll 22.07.2011 21:57

Хорошее объяснение. Также просмотрите это: iliadraznin.com/2012/03/…

will824 24.07.2013 01:12

Согласен с Майкл Харен.

Также рассмотрите возможность использования массивов и присоединения, если производительность действительно является проблемой.

var buffer = ["<a href='", url, "'>click here</a>"];
buffer.push("More stuff");
alert(buffer.join(""));

Я знаю, что выбран правильный ответ, но в этом ответе есть более полезный пример.

Jason Sperske 07.04.2010 20:41

Вау просто вау. Сравните эти две скрипки в IE7: jsfiddle.net/9uS4n/5 (быстро) против jsfiddle.net/9uS4n/2 (медленно). Похоже, что при использовании этой техники производительность улучшается как минимум в 1000 раз.

Kirk Woll 22.07.2011 21:54

@KirkWoll: Возможно, в будущем захочется использовать jsPerf, чтобы мы могли легко сравнивать результаты.

rvighne 17.08.2014 23:15

Я тоже делал это в последнее время, похожий стиль кода на .NET StringBuilder, var sb = []; sb.push («раздел 1»); sb.push («раздел 2»); вернуть sb.join ('');

Sam Jones 29.12.2014 17:22

Этот jsPerf jsperf.com/join-concat/2, упомянутый в: stackoverflow.com/questions/16696632/…, похоже, указывает на то, что += быстрее.

Ciro Santilli TRUMP BAN IS BAD 13.10.2019 01:55

Насколько мне известно, каждая конкатенация подразумевает перераспределение памяти. Таким образом, проблема не в том, какой оператор это сделал, а в том, чтобы уменьшить количество конкатенаций. Например, по возможности выполняйте конкатенации вне итерационных структур.

На самом деле это неплохой совет, я не знаю, почему он так сильно отклонен. Я знаю, что он не отвечает на конкретный вопрос, но он заслуживает признания как в целом хороший совет.

eyelidlessness 24.04.2010 10:33

Как уже отметили некоторые пользователи: это не имеет отношения к маленьким строкам.

А новые движки JavaScript в Firefox, Safari или Google Chrome оптимизируют так, чтобы

"<a href='" + url + "'>click here</a>";

так же быстро, как

["<a href='", url, "'>click here</a>"].join("");
Ответ принят как подходящий

Internet Explorer - единственный браузер, который действительно страдает от этого в современном мире. (Версии 5, 6 и 7 были очень медленными. 8 не показывает такой же деградации.) Более того, IE становится все медленнее и медленнее, чем длиннее ваша строка.

Если вам нужно объединить длинные строки, обязательно используйте технику array.join. (Или какую-нибудь оболочку StringBuffer для удобства чтения.) Но если ваши строки короткие, не беспокойтесь.

Мне нравится использовать функциональный стиль, например:

function href(url,txt) {
  return "<a href='" +url+ "'>" +txt+ "</a>"
}

function li(txt) {
  return "<li>" +txt+ "</li>"
}

function ul(arr) {
  return "<ul>" + arr.map(li).join("") + "</ul>"
}

document.write(
  ul(
    [
      href("http://url1","link1"),
      href("http://url2","link2"),
      href("http://url3","link3")
    ]
  )
)

Этот стиль выглядит читабельным и прозрачным. Это приводит к созданию утилит, уменьшающих повторение кода.

Это также имеет тенденцию автоматически использовать промежуточные строки.

С помощью jspref.com довольно легко настроить быстрый тест и проверить вариации производительности Javascript. Которого, вероятно, не было, когда задавали этот вопрос Но тем, кто сталкивается с этим вопросом, стоит заглянуть на сайт.

Я провел быстрый тест различных методов конкатенации на http://jsperf.com/string-concat-methods-test.

Судя по этому, в настоящее время похоже, что конкатенация с оператором + определенно верный путь. Если только я не читаю неправильно. Что вполне правдоподобно.

Richard 28.11.2013 15:24

Более простой для чтения метод экономит людям ощутимое количество времени при просмотре кода, тогда как «более быстрый» метод тратит только незаметное и, вероятно, незначительное количество времени, когда люди просматривают страницу.

Я знаю, что это неубедительное сообщение, но я случайно опубликовал что-то совершенно другое, думая, что это другая ветка, и я не знаю, как удалять сообщения. Виноват...

Другие вопросы по теме