Saya sibuk dengan implementasi logis proyek pada hari kerja. Saya punya waktu pada hari Sabtu, jadi saya mengeluarkan pemikiran bahasa Inggris yang tebal di Java dari rak buku dan membaca splicing objek string. Lihat buku ini sebagai terjemahan, tambahkan apa yang Anda pikirkan, dan tulis artikel ini untuk merekamnya.
Objek String Immutable
Di Java, objek string tidak dapat diubah (tidak dapat diubah). Dalam kode, Anda dapat membuat beberapa alias untuk objek string. Tetapi referensi alias ini sama.
Misalnya, S1 dan S2 adalah alias untuk objek "droidyue.com", dan alias disimpan dalam referensi ke objek nyata. Jadi s1 = s2
String s1 = "droidyue.com"; string s2 = s1; system.out.println ("s1 dan s2 memiliki referensi yang sama =" + (s1 == s2));Satu -satunya operator yang kelebihan beban di Java
Di Java, satu -satunya operator yang kelebihan beban terkait dengan splicing string. +,+=. Selain itu, desainer Java tidak mengizinkan kelebihan muatan operator lain.
Analisis splicing
Apakah benar -benar ada biaya kinerja?
Setelah memahami dua poin di atas, Anda mungkin memiliki pemikiran seperti itu. Karena objek Sting tidak dapat diubah, splicing dari beberapa (tiga atau lebih) string pasti akan menghasilkan objek string menengah yang tidak perlu.
String username = "Andy"; String Age = "24"; String Job = "Developer"; String Info = UserName + Age + Job;
Untuk mendapatkan info di atas, nama pengguna dan usia akan disambung untuk menghasilkan objek string sementara T1, dengan konten Andy24, dan kemudian T1 dan pekerjaan akan disambung untuk menghasilkan objek info yang kita butuhkan pada akhirnya. Di antara mereka, T1 menengah dihasilkan, dan setelah T1 dibuat, itu tidak akan didaur ulang secara otomatis, yang pasti akan menempati sejumlah ruang. Jika itu adalah splicing banyak (dengan asumsi ratusan, lebih umum dalam panggilan tostring ke objek), maka biaya akan lebih besar dan kinerjanya akan jauh lebih rendah.
Pemrosesan Optimasi Kompiler
Apakah benar -benar ada biaya kinerja di atas? Penyambungan string sangat umum, apakah tidak ada optimasi pemrosesan khusus? Jawabannya adalah bahwa optimasi ini dilakukan ketika kompiler mengkompilasi .java ke bytecode.
Jika program Java ingin berjalan, itu akan memakan waktu dua periode, kompilasi waktu dan jalankan waktu. Pada waktu kompilasi, kompiler java (kompiler) mengubah file java menjadi bytecode. Saat runtime, Java Virtual Machine (JVM) menjalankan bytecode yang dihasilkan waktu kompilasi. Melalui dua periode ini, Java telah mencapai apa yang disebut kompilasi dan berjalan di mana-mana.
Mari kita bereksperimen dengan optimisasi apa yang dibuat selama periode kompilasi, dan kami membuat sepotong kode yang mungkin memiliki biaya kinerja.
concatenation kelas publik {public static void main (string [] args) {string username = "andy"; Usia string = "24"; String job = "pengembang"; Info string = nama pengguna + usia + pekerjaan; System.out.println (info); }}Kompilasi concatenation.java. Dapatkan concatenation.class
javac concatenation.java
Kemudian kami menggunakan JAVAP untuk mendekompilasi file concatenation.class yang dikompilasi. JAVAP -C Concatenation. Jika perintah JAVAP tidak ditemukan, silakan pertimbangkan untuk menambahkan direktori di mana JAVAP berada di variabel lingkungan atau menggunakan jalur lengkap JAVAP.
17: 22: 04 -androidyue ~/workspace_adt/string/src $ javap -c ConcatenationCompiled dari "concatenation.java" complateNation kelas publik {concatenation publik (); Kode: 0: Aload_0 1: Invokespecial #1 // Metode Java/Lang/Object. "<inin>" :() V 4: mengembalikan public static void main (java.lang.string []); Kode: 0: LDC #2 // String Andy 2: Store_1 3: LDC #3 // String 24 5: Store_2 6: LDC #4 // Pengembang String 8: Store_3 9: Baru #5 // Kelas Java/Lang/StringBuilder 12: Dup 13: Invokespecial #6 // Metode Java/Lang/Lang/Lang/String/DUP. Invokevirtual #7 // Metode Java/Lang/StringBuilder.Append: (ljava/lang/string;) ljava/lang/stringBuilder; 20: Aload_2 21: Invokevirtual #7 // Metode Java/Lang/StringBuilder.Append: (ljava/lang/string;) ljava/lang/stringBuilder; 24: Aload_3 25: Invokevirtual #7 // Metode Java/Lang/StringBuilder.Append: (ljava/lang/string;) ljava/lang/stringBuilder; 28: Invokevirtual #8 // Metode Java/Lang/StringBuilder.tostring :() ljava/lang/string; 31: Store 4 33: Getstatic #9 // Field Java/Lang/System.out: ljava/io/printstream; 36: Aload 4 38: Invokevirtual #10 // Metode Java/io/printStream.println: (ljava/lang/string;) v 41: return}Di antara mereka, LDC, toko, dll. Adalah instruksi java bytecode, mirip dengan instruksi perakitan. Komentar berikut menggunakan konten terkait Java untuk penjelasan. Kita dapat melihat bahwa ada banyak StringBuilders di atasnya, tetapi kami memanggilnya tanpa tampilan dalam kode Java. Ini adalah optimasi yang dibuat oleh kompiler Java. Ketika kompiler Java menemukan splicing string, itu akan membuat objek StringBuilder. Penyambungan di belakangnya sebenarnya memanggil metode append dari objek StringBuilder. Dengan cara ini, tidak akan ada masalah yang kita khawatirkan.
Optimalisasi kompiler saja?
Karena kompiler telah membantu kami mengoptimalkan, apakah cukup untuk hanya mengandalkan optimasi kompiler? Tentu saja tidak.
Mari kita lihat sepotong kode yang belum dioptimalkan untuk kinerja rendah
public void implicitUseStringBuilder (string [] nilai) {string result = ""; untuk (int i = 0; i <values.length; i ++) {result += values [i]; } System.out.println (hasil);}Kompilasi dengan javac dan lihat dengan javap
11: Baru #5 // Kelas Java/Lang/StringBuilder 14: Dup 15: Invokespecial #6 // Metode Java/Lang/StringBuilder. "<inin>" :() V 18: Aload_2 19: Invokevirtual #7 // Metode 31: Store_2 32: IIN 3, 1 35: GOTO: GOTO #7 // METODE 31: STORE_2 32: IIN 3, 1 35: GOTO: GOTO #7 // METODE 31: STORE_2 32: IIN 3, 1 35: GOTO: java/lang/system.out: ljava/io/printstream; 41: Aload_2 42: Invokevirtual #10 // Metode Java/io/printStream.println: (ljava/lang/string;) v 45: return
Di antara mereka 8: IF_ICMPGE 38 dan 35: GOTO 5 membentuk loop. 8: IF_ICMPGE 38 berarti bahwa jika perbandingan integer dari tumpukan operan JVM lebih besar dari atau sama dengan (hasil yang berlawanan dari i <values.length) adalah benar, kemudian melompat ke baris 38 (System.out). 35: GOTO 5 berarti melompat langsung ke baris 5.
Tetapi ada hal yang sangat penting di sini bahwa pembuatan objek StringBuilder terjadi di antara loop, yang berarti berapa kali loop akan membuat objek StringBuilder, yang jelas tidak baik. Kode tingkat rendah telanjang.
Mengoptimalkannya sedikit untuk secara instan meningkatkan kualitas.
public void ExplicitUseStringBuilder (string [] nilai) {stringBuilder result = new stringBuilder (); untuk (int i = 0; i <values.length; i ++) {result.append (nilai [i]); }}Informasi Kompilasi yang sesuai
11: aload_1 12: arraylength 13: if_icmpge 30 16: aload_2 17: aload_1 18: iload_3 19: aaload 20: Invokevirtual #7 // Metode java/lang/stringbuilder.append: (ljava/lang/string;) ljava/lang/lang/stringbu/langbu: ljava/lang; 23: Pop 24: Iinc 3, 1 27: GOTO 10 30: kembali
Seperti yang dapat dilihat dari atas, 13: IF_ICMPGE 30 dan 27: GOTO 10 membentuk loop loop, sedangkan 0: baru #5 berada di luar loop, jadi StringBuilder tidak dibuat beberapa kali.
Secara umum, kita perlu mencoba menghindari penciptaan pembuat string implisit atau eksplisit di badan loop. Oleh karena itu, mereka yang memahami bagaimana kode tersebut dikompilasi dan bagaimana ia dieksekusi secara internal memiliki tingkat kode yang relatif tinggi.
Jika ada kesalahan dalam artikel di atas, silakan mengkritik dan memperbaikinya.
Di atas adalah memilah informasi tentang penyambungan string Java, dan kami akan terus menambahkan informasi yang relevan di masa depan. Terima kasih atas dukungan Anda untuk situs web ini!