Kata pengantar
Di antara pengembang Java, hunian sumber daya yang tinggi sering menjadi topik hangat.
Mari kita bahas secara mendalam mengapa menempati sumber daya tinggi.
Di Java, objek string tidak dapat diubah, artinya begitu dibuat, Anda tidak dapat mengubahnya lagi. Jadi ketika kita menyambungkan string, kita membuat string baru, dan yang lama ditandai oleh pengumpul sampah.
Jika kami memproses jutaan string, maka kami menghasilkan jutaan string tambahan untuk diproses oleh pengumpul sampah.
Di sebagian besar tutorial, Anda dapat melihat bahwa menggunakan + tanda untuk splice string akan menghasilkan banyak string, menghasilkan kinerja yang buruk. Disarankan untuk menggunakan StringBuffer/StringBuilder untuk menyambungkan.
Tapi apakah ini masalahnya?
Artikel ini telah melakukan percobaan berikut di JDK8:
public static void main (string [] args) {string result = ""; Hasil += "beberapa data lagi"; System.out.println (hasil); }Mendekompilasi melalui javap -c untuk mendapatkan:
Kode: 0: aload_0 // dorong 'ini' ke stack 1: Invokespecial #1 // Invoke Object Class Constructor // Pop 'This' Ref dari Stack 4: Return // Return dari konstruktor public static void main (java.lang.string []); Code: 0: ldc #2 // Load constant #2 on to the stack 2: store_1 // Create local var from stack (pop #2) 3: new #3 // Push new StringBuilder ref on stack 6: dup // Duplicate value on top of the stack 7: invokespecial #4 // Invoke StringBuilder constructor // pop object reference 10: aload_1 // Push local variable containing #2 11: Invokevirtual #5 // Metode Invoke StringBuilder.Append () // Referensi Pop OBJ + Parameter // Hasil Push (StringBuilder Ref) 14: LDC #6 // Push "beberapa data lebih lanjut" pada stack 16: Invokevirtual #5 // Invoke StringBuilder.Append // Pop Twades Twee, PUSTROVIUAL. 22: STORE_1 // Buat var lokal dari stack (pop #6) 23: getStatic #8 // push value system.out: printStream 26: aload_1 // dorong variabel lokal yang berisi #6 27: Invokevirtual #9 // Return / Returning.
Anda dapat melihat bahwa kompiler Java mengoptimalkan bytecode yang dihasilkan, secara otomatis membuat stringbuilder, dan melakukan operasi apend.
Karena substring dari string akhir sudah dikenal pada waktu kompilasi, kompiler Java akan melakukan optimasi di atas dalam kasus ini. Optimalisasi ini disebut optimasi gabungan string statis dan telah diaktifkan sejak JDK5.
Apakah itu berarti bahwa setelah JDK5, kita tidak perlu lagi secara manual menghasilkan StringBuilder, dan kita dapat mencapai kinerja yang sama melalui tanda +?
Mari kita coba string splicing secara dinamis:
String splicing dinamis mengacu pada substring yang hanya diketahui saat runtime. Misalnya, menambahkan string ke loop:
public static void main (string [] args) {string result = ""; untuk (int i = 0; i <10; i ++) {hasil+= "beberapa data lagi"; } System.out.println (hasil); }Juga terurai:
Kode: 0: aload_0 // dorong 'ini' ke stack 1: Invokespecial #1 // Invoke Object Class Constructor // Pop 'This' Ref dari Stack 4: Return // Return dari konstruktor public static void main (java.lang.string []); Kode: 0: LDC #2 // Muat konstanta #2 ke stack 2: store_1 // buat var lokal dari stack, pop #2 3: iconst_0 // nilai push 0 ke tumpukan 4: iStore_2 // nilai pop dan simpan di var lokal 5: iload_2 // dorong var lokal 2 on ke stack 6: i2d var 5: iload_2 // dorong var lokal 2 on to the stack 6: i2d / i2d / iLoad_2 // dorong var lokal 2 on to the stack 6: i2d / i2d / iLoad_2 // dorong var lokal 2 on to the stack 6: i2d / iload oNT / ON DOUDE VAR LOCAL 2 ON TOTKE 6: I2D I2D / ILOAD_2 // DOUPLE VAR LOCAL 2 ON TO TUMPUT 6: I2D I2 LDC2_W #3 // Dorong konstanta 10e6 ke stack 10: dcmpg // Bandingkan dua ganda di atas stack // pop dua kali, dorong hasil: -1, 0 atau 1 11: ifge 40 // jika nilai di atas stack lebih besar // dari atau sama dengan 0 (pop sekali) // cabang ke instruksi di kode 40 14: duid // dari atau sama dengan 0 (Pop) // Cabang ke Instruksi di Kode 40 14: DULU // DARI DARI ATAU EXTORM DENGAN 0 (POP) // Cabang ke Kode 40 14: DUIP BARU #5 // DARI ATAU EXTURE DENGAN 0 (POP) // REK TO CODE 40 14: DUIP BARU #5 // DARI ATAU SEPERTI POP (POP) // Cabang ke Code 40 14: DULUT / DOLD LEBIH Top of the Stack 18: Invokespecial #6 // Invoke StringBuilder Constructor // Referensi Objek Pop 21: Aload_1 // Dorong Lokal Var 1 (String Kosong) // Ke Tumpukan 22: Invokevirtual #7 // Invoke StringBuilder.APPEND // POP OBJ REF + PARAM, PUSH Hasil 25: LDC #8 // DATA "Some" Some "Some B di Stage 22: LDC #8 // PUCK" POP OBJ REF, Some LDC #7: LDC #8 // Some (Ldc #8 // StringBuilder.Append // Pop Obj Ref + Param, Hasil Push 30: Invokevirtual #9 // Invoke StringBuilder.ToString // Referensi Objek Pop 33: Store_1 // Buat Var Lokal Dari Stack (Pop) 34: Iinc 2, 1 // Peningkatan Variabel Lokal 2 dengan 1 37: GOTO 5 // PINGKATAN PERANG aload_1 // dorong var lokal 1 (string hasil) 44: Invokevirtual #11 // Metode Invoke printStream.println () // pop dua kali (objek ref + parameter) 47: return // return void dari metode
Anda dapat melihat bahwa StringBuilder baru di 14, tetapi pada usia 37, Goto 5. Selama loop, optimasi tidak tercapai, dan pembuat string baru terus -menerus dihasilkan.
Jadi kode di atas serupa:
String result = ""; for (int i = 0; i <10; i ++) {StringBuilder tmp = new StringBuilder (); tmp.append (hasil); tmp.append ("beberapa data lagi"); hasil = tmp.toString ();} system.out.println (hasil);Anda dapat melihat bahwa StringBuilders baru terus -menerus dihasilkan, dan melalui Tostring, StringBuilder asli tidak akan lagi dirujuk, sebagai sampah, dan juga meningkatkan biaya GC.
Oleh karena itu, dalam penggunaan aktual, ketika Anda tidak dapat membedakan apakah suatu string statis atau dinamis, gunakan StringBuilder.
Referensi:
http://www.pellegrino.link/2015/08/22/string-concatenation-with-java-8.html
Meringkaskan
Di atas adalah seluruh konten artikel ini. Saya berharap konten artikel ini memiliki nilai referensi tertentu untuk studi atau pekerjaan semua orang. Jika Anda memiliki pertanyaan, Anda dapat meninggalkan pesan untuk berkomunikasi. Terima kasih atas dukungan Anda ke wulin.com.