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?


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

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.


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


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.


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(""));

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


18

Coba ini:

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

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("");

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).


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.


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...


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 .


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.


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.


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.


Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.