web-dev-qa-db-ja.com

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()よりもパフォーマンスが低いと主張しています。これは本当ですか?

89
Dónal

Internet Explorerは、今日の世界でこれに本当に苦しむ唯一のブラウザです。 (バージョン5、6、および7は非常に低速でした。8は同じ劣化を示しません。)さらに、IEは文字列が長くなるほど遅くなります。

連結する長い文字列がある場合は、array.joinテクニックを確実に使用してください。 (または読みやすくするために、これを取り巻くStringBufferラッパー。)しかし、文字列が短い場合は気にしないでください。

46
pcorcoran

あなたの例は、パフォーマンスが著しく異なる可能性が非常に低いという点で、良い例ではありません。あなたの例では、一方に対する他方のパフォーマンスの向上は無視できるため、可読性はパフォーマンスよりも優れているはずです。配列(StringBuffer)の利点は、多くの連結を行っている場合にのみ明らかです。それでも、あなたの走行距離はブラウザに大きく依存します。

これは、さまざまなブラウザーでさまざまなJavaScript連結方法を使用してパフォーマンスを示す詳細なパフォーマンス分析です。 文字列パフォーマンス分析

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

もっと:
IEでのAjaxian >> String Performance:Array.join vs + = continue

102
Eric Schoonover

はい、それは本当ですが、気にする必要はありません。読みやすいものを使用してください。アプリのベンチマークを行う必要がある場合は、ボトルネックに注目してください。

文字列の連結がボトルネックになることはないと思います。

37
Michael Haren

Michael Haren と合意しました。

また、実際にパフォーマンスが問題になる場合は、配列の使用と結合を検討してください。

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

これを試して:

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

JavaScriptにはネイティブのStringBufferオブジェクトがないため、これは使用しているライブラリ、または異常なホスト環境の機能(ブラウザではない)からのものであると想定しています。

ライブラリ(JSで記述された)が何かをより速く生成することを疑いますが、ネイティブのStringBufferオブジェクトはそうするかもしれません。最終的な回答はプロファイラーで見つけることができます(ブラウザーで実行している場合、FirebugはFirefoxで見つかったJSエンジンのプロファイラーを提供します)。

8
Quentin

すでにいくつかのユーザーが指摘しているように:これは小さな文字列には無関係です。

Firefox、Safari、またはGoogleの新しいJavaScriptエンジンChrome最適化

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

と同じくらい速いです

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

クヌースの言葉を借りると、「時期尚早な最適化はすべての悪の根源です!」いずれにせよ、小さな違いはおそらく最終的にはあまり効果がありません。もっと読みやすいものを選びます。

6
William Keller

読みやすい方法は、コードを見るときに人間が知覚できる時間を節約しますが、「高速」の方法は、ページを閲覧しているときに知覚できないほど無視できる時間を浪費するだけです。

私はこの投稿が不完全であることを知っていますが、これが別のスレッドだと思ってまったく違うものを誤って投稿しました。投稿を削除する方法がわかりません。私の悪い...

4
Ed Kern

jspref.com を使用して、簡単なベンチマークを設定し、Javascriptのパフォーマンスのバリエーションを確認するのは非常に簡単です。この質問が尋ねられたとき、おそらくそれは周りにはなかったでしょう。しかし、この質問につまずく人々のために、彼らはサイトを見なければなりません。

http://jsperf.com/string-concat-methods-test で、さまざまな連結方法の簡単なテストを行いました。

3
James McMahon

私は次のような機能的なスタイルを使用するのが好きです:

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

このスタイルは読みやすく、透明に見えます。コードの繰り返しを減らすユーティリティの作成につながります。

また、これは中間文字列を自動的に使用する傾向があります。

2
jasonc65

私の知る限り、すべての連結はメモリの再割り当てを意味します。そのため、問題はそれを行うために使用される演算子ではなく、解決策は連結の数を減らすことです。たとえば、可能な場合は、反復構造の外側で連結を行います。

1
David Ameller

はい、通常のベンチマークによると。 E.G: http://mckoss.com/jscript/SpeedTrial.htm

しかし、小さな弦の場合、これは無関係です。非常に大きな文字列でのパフォーマンスのみが重要です。さらに、ほとんどのJSスクリプトでは、ボトルネックが十分ではないため、文字列操作にほとんど影響しません。

DOMの操作を監視した方がよいでしょう。

0
e-satis