adalah operator + kurang berkinerja dibandingkan StringBuffer.append ()

91

Di tim saya, kami biasanya melakukan penggabungan string seperti ini:

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

Jelas berikut ini jauh lebih mudah dibaca:

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

Tetapi para ahli JS mengklaim bahwa +operator tersebut kurang berkinerja dibandingkan StringBuffer.append(). Apakah ini benar?

Dónal
sumber
93
Tidak ada StringBuffer di javascript
Tomas
7
Don, apakah Anda mengacu pada Jawa?
James McMahon
Pengalaman saya [].join('')menunjukkan beberapa perilaku yang benar-benar terprogram, jadi saya kembali ke +: - /
martyglaubitz
1
Saya tahu pertanyaan mendasar di sini adalah tentang penggabungan string tetapi Anda harus berhati-hati saat membuat elemen html seperti ini. Contoh Anda bisa rusak jika urlberisi 'atau \n.
styfle
Kemungkinan duplikat dari cara paling efisien untuk menggabungkan string di JavaScript?
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Jawaban:

46

Internet Explorer adalah satu-satunya browser yang benar-benar menderita seperti ini di dunia saat ini. (Versi 5, 6, dan 7 adalah dog slow. 8 tidak menunjukkan degradasi yang sama.) Terlebih lagi, IE semakin lambat dan semakin lambat semakin panjang string Anda.

Jika Anda memiliki string panjang untuk digabungkan maka pasti gunakan teknik array.join. (Atau beberapa pembungkus StringBuffer di sekitar ini, agar terbaca.) Tetapi jika string Anda pendek, jangan repot-repot.

pcorcoran.dll
sumber
102

Teladan Anda tidak bagus karena sangat kecil kemungkinan kinerjanya akan berbeda secara signifikan. Dalam contoh Anda, keterbacaan harus mengalahkan kinerja karena perolehan kinerja satu vs yang lain dapat diabaikan. Manfaat dari sebuah array (StringBuffer) hanya terlihat ketika Anda melakukan banyak concatentations. Meskipun demikian, jarak tempuh Anda bisa sangat bergantung pada browser Anda.

Berikut adalah analisis kinerja terperinci yang menunjukkan kinerja menggunakan semua metode penggabungan JavaScript yang berbeda di banyak browser yang berbeda; Kinerja String dan Analisis

gabung () sekali, concat () sekali, gabung () untuk, + = untuk, concat () untuk

Selengkapnya:
Ajaxian >> Performa String di IE: Array.join vs + = lanjutan

Eric Schoonover
sumber
9
Mengenai grafik, seandainya tidak jelas; lebih rendah lebih baik.
Teekin
1
"Hal pertama yang pertama dengan peningkatan kinerja dengan IE7, kami tidak perlu lagi mempertimbangkan untuk menggunakan jalur alternatif saat melakukan operasi string skala besar; menggunakan Array.join dalam situasi berulang tidak memberi Anda keuntungan besar selain menggunakan + = dalam situasi yang sama. Selain itu, perbedaan dengan IE6 cukup kecil sehingga Anda tidak perlu repot mencari versi khusus tersebut. "
Chris S
2
@ Chris, itu tidak benar. Bandingkan dua biola ini di IE7 : jsfiddle.net/9uS4n/5 (cepat) vs. jsfiddle.net/9uS4n/2 (lambat). Tampaknya setidaknya ada peningkatan kinerja 1000 kali dengan menggunakan join()teknik ini.
Kirk Woll
Penjelasan yang bagus. Harap tinjau juga ini: iliadraznin.com/2012/03/…
will824
37

Ya itu benar tetapi Anda tidak perlu peduli. Pilih salah satu yang lebih mudah dibaca. Jika Anda harus mengukur aplikasi Anda, maka fokuslah pada kemacetan.

Saya kira penggabungan string tidak akan menjadi hambatan Anda.

Michael Haren
sumber
31

Setuju dengan Michael Haren .

Juga pertimbangkan penggunaan array dan gabung jika kinerja memang menjadi masalah.

var buffer = ["<a href='", url, "'>click here</a>"];
buffer.push("More stuff");
alert(buffer.join(""));
Frank Krueger
sumber
3
Saya tahu bahwa jawaban yang benar telah dipilih, tetapi jawaban ini memiliki contoh yang lebih berguna.
Jason Sperske
1
Wow Hanya wow. Bandingkan dua biola ini di IE7 : jsfiddle.net/9uS4n/5 (cepat) vs. jsfiddle.net/9uS4n/2 (lambat). Tampaknya setidaknya ada peningkatan kinerja 1000 kali lipat dengan menggunakan teknik ini.
Kirk Woll
@KirkWoll: Mungkin ingin menggunakan jsPerf di masa mendatang sehingga kami dapat membandingkan hasilnya dengan mudah.
rvighne
Saya telah melakukan ini akhir-akhir ini juga, gaya kode yang mirip dengan .NET StringBuilder, var sb = []; sb.push ("bagian 1"); sb.push ("bagian 2"); return sb.join ('');
Sam Jones
JsPerf jsperf.com/join-concat/2 ini disebutkan di: stackoverflow.com/questions/16696632/… tampaknya menunjukkan bahwa +=lebih cepat.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
18

Coba ini:

var s = ["<a href='", url, "'>click here</a>"].join("");
Rahul
sumber
Nah, posting yang Anda tautkan dalam jawaban Anda secara khusus mencoba untuk menyangkal "mitos" Array.join yang disarankan oleh jawaban saya. Jadi mungkin tidak. Saya hanya memposting apa yang saya lihat lebih cepat dalam praktiknya.
Rahul
suka metode string concat ini.
bkwdesign
8

Seperti yang sudah dicatat oleh beberapa pengguna: Ini tidak relevan untuk string kecil.

Dan mesin JavaScript baru di Firefox, Safari atau Google Chrome mengoptimalkannya

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

secepat

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

JavaScript tidak memiliki objek StringBuffer asli, jadi saya berasumsi ini dari perpustakaan yang Anda gunakan, atau fitur dari lingkungan host yang tidak biasa (yaitu bukan browser).

Saya ragu perpustakaan (ditulis dalam JS) akan menghasilkan sesuatu yang lebih cepat, meskipun objek StringBuffer asli mungkin. Jawaban pasti dapat ditemukan dengan profiler (jika Anda menjalankan di browser, Firebug akan memberi Anda profiler untuk mesin JS yang ditemukan di Firefox).

Quentin
sumber
6

Dalam kata-kata Knuth, "optimasi prematur adalah akar dari segala kejahatan!" Perbedaan kecil dengan cara apa pun kemungkinan besar tidak akan banyak berpengaruh pada akhirnya; Saya akan memilih yang lebih mudah dibaca.

William Keller
sumber
1
Secara tradisional StringBuffer digunakan selama penggabungan karena yang pertama memiliki kompleksitas waktu O (N) sedangkan yang terakhir sebagai O (N ^ 2), sehingga perbedaannya signifikan untuk N besar (tetapi tidak untuk N kecil). Dalam kasus apapun, skenario O (N ^ 2) mungkin tidak terjadi di JavaScript tergantung pada lingkungan yang digunakan.
redcalx
4

Metode yang lebih mudah dibaca menghemat waktu yang terlihat saat melihat kode, sedangkan metode "lebih cepat" hanya membuang waktu yang tidak terlihat dan kemungkinan dapat diabaikan saat orang menjelajahi halaman.

Saya tahu posting ini payah, tetapi saya tidak sengaja memposting sesuatu yang sama sekali berbeda dengan pemikiran ini adalah utas yang berbeda dan saya tidak tahu cara menghapus posting. Salahku...

Ed Kern
sumber
3

Sangat mudah untuk menyiapkan tolok ukur cepat dan memeriksa variasi kinerja Javascript menggunakan jspref.com . Yang mungkin tidak ada saat pertanyaan ini diajukan. Tetapi bagi orang-orang yang tersandung pada pertanyaan ini, mereka harus melihat-lihat situs tersebut.

Saya melakukan tes cepat dari berbagai metode penggabungan di http://jsperf.com/string-concat-methods-test .

James McMahon
sumber
Dilihat dari itu, sepertinya saat ini penggabungan dengan operator + jelas merupakan cara yang harus dilakukan. Kecuali saya salah membacanya. Yang sepenuhnya masuk akal.
Richard
2

Saya suka menggunakan gaya fungsional, seperti:

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

Gaya ini terlihat mudah dibaca dan transparan. Ini mengarah pada pembuatan utilitas yang mengurangi pengulangan dalam kode.

Ini juga cenderung menggunakan string perantara secara otomatis.

jasonc65.dll
sumber
1

Sejauh yang saya tahu, setiap penggabungan menyiratkan realokasi memori. Jadi masalahnya bukan operator yang biasa melakukannya, solusinya adalah mengurangi jumlah penggabungan. Misalnya melakukan penggabungan di luar struktur iterasi bila Anda bisa.

David Ameller
sumber
Ini sebenarnya bukan nasihat yang buruk, saya tidak tahu mengapa itu ditolak begitu banyak. Saya tahu ini tidak menjawab pertanyaan spesifik, tetapi layak mendapat pengakuan sebagai nasihat yang baik secara umum.
kelopak mata tanpa kelopak mata
0

Ya, menurut tolok ukur biasa. Misalnya: http://mckoss.com/jscript/SpeedTrial.htm .

Tetapi untuk string kecil, ini tidak relevan. Anda hanya akan peduli dengan penampilan dengan string yang sangat besar. Terlebih lagi, di sebagian besar skrip JS, leher botol jarang ada pada manipulasi string karena jumlahnya tidak cukup.

Anda sebaiknya memperhatikan manipulasi DOM.

e-satis
sumber
Tautan sudah mati .. https://web.archive.org/web/20150912072015/http://mckoss.com/jscript/SpeedTrial.htm menunjuk ke versi arsip web.
Tony