является ли оператор + менее производительным, чем StringBuffer.append()
-
02-07-2019 - |
Вопрос
В моей команде мы обычно выполняем конкатентацию строк следующим образом:
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 во многих различных браузерах; Анализ производительности струн
Еще:
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.