является ли оператор + менее производительным, чем StringBuffer.append()

StackOverflow https://stackoverflow.com/questions/112158

Вопрос

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

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().Это действительно так?

Это было полезно?

Решение

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Как уже отметили некоторые пользователи:Это не имеет значения для маленьких строк.

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

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

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

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

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

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

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

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

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

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

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")
    ]
  )
)

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top