Apakah ada perbedaan yang nyata antara penggunaan String.format
dan penggabungan String di Jawa?
Saya cenderung menggunakan String.format
tetapi kadang-kadang akan terpeleset dan menggunakan gabungan. Saya bertanya-tanya apakah yang satu lebih baik dari yang lain.
Cara saya melihatnya, String.format
memberi Anda lebih banyak kekuatan dalam "memformat" string; dan rangkuman berarti Anda tidak perlu khawatir tentang secara tidak sengaja memasukkan% s ekstra atau melewatkannya.
String.format
juga lebih pendek.
Yang mana yang lebih mudah dibaca tergantung pada cara kerja kepala Anda.
java
string
concatenation
string.format
Omar Kooheji
sumber
sumber
Jawaban:
Saya menyarankan bahwa ini adalah praktik yang lebih baik untuk digunakan
String.format()
. Alasan utamanya adalah bahwaString.format()
dapat lebih mudah dilokalisasi dengan teks yang dimuat dari file sumber daya sedangkan rangkuman tidak dapat dilokalisasi tanpa menghasilkan executable baru dengan kode yang berbeda untuk setiap bahasa.Jika Anda berencana aplikasi Anda dapat diterjemahkan secara lokal, Anda juga harus membiasakan diri menentukan posisi argumen untuk token format Anda juga:
Ini kemudian dapat dilokalkan dan mengganti nama dan token waktu tanpa memerlukan kompilasi ulang dari executable untuk menjelaskan urutan pemesanan yang berbeda. Dengan posisi argumen Anda juga dapat menggunakan kembali argumen yang sama tanpa melewatkannya ke dalam fungsi dua kali:
sumber
Tentang kinerja:
Hasil waktu adalah sebagai berikut:
Oleh karena itu, penggabungan jauh lebih cepat daripada String.format.
sumber
javap -c StringTest.class
Anda akan melihat bahwa kompiler mengubah "+" menjadi StringBuilder secara otomatis hanya jika Anda tidak berada dalam satu lingkaran. Jika penggabungan semua dilakukan pada satu baris sama dengan menggunakan '+', tetapi jika Anda menggunakanmyString += "morechars";
ataumyString += anotherString;
pada beberapa baris Anda akan melihat bahwa lebih dari satu StringBuilder mungkin dibuat, jadi menggunakan "+" tidak selalu seefisien sebagai StringBuilder.+
tidak dapat dikonversiStringBuilder.append()
tetapinew StringBuilder()
terjadi pada setiap iterasi.Karena ada diskusi tentang kinerja saya pikir saya akan menambahkan perbandingan yang termasuk StringBuilder. Ini sebenarnya lebih cepat daripada concat dan, tentu saja opsi String.format.
Untuk membuat ini semacam perbandingan apel dengan apel, saya instantiate StringBuilder baru di loop daripada di luar (ini sebenarnya lebih cepat daripada hanya melakukan satu instantiasi yang paling mungkin karena overhead dari ruang alokasi ulang untuk menambahkan looping pada akhir satu pembangun).
sumber
String
. Tes StringBuilder, agar adil, membutuhkan langkah terakhir yang mengubah konten StringBuilder menjadi sebuah String. Anda melakukannya dengan meneleponbldString.toString()
. Saya harap itu menjelaskannya?String s = bldString.toString();
Timing adalah dengan Rangkaian dan stringbuilder hampir setara dengan satu sama lain:Format = 1520 millisecond
,Concatenation = 167 millisecond
,String Builder = 173 millisecond
aku berlari mereka dalam satu lingkaran dan rata-rata masing-masing untuk mendapatkan yang baik rep: (pra-JVM optimasi, akan mencoba 10.000 + lingkaran ketika saya mendapatkan waktu)Satu masalah
.format
adalah Anda kehilangan keamanan tipe statis. Anda dapat memiliki terlalu sedikit argumen untuk format Anda, dan Anda dapat memiliki tipe yang salah untuk penentu format - keduanya mengarah padaIllegalFormatException
saat runtime , sehingga Anda mungkin berakhir dengan kode logging yang merusak produksi.Sebaliknya, argumen untuk
+
dapat diuji oleh kompiler.Itu sejarah keamanan dariprintf(Di mana
format
fungsi dimodelkan) panjang dan menakutkan.sumber
Anda mendapat jawaban Anda di sana.
Ini masalah selera pribadi.
Rangkaian string sedikit lebih cepat, saya kira, tetapi itu harus diabaikan.
sumber
Berikut ini tes dengan beberapa ukuran sampel dalam milidetik.
}
sumber
Berikut ini tes yang sama seperti di atas dengan modifikasi memanggil metode toString () pada StringBuilder . Hasil di bawah ini menunjukkan bahwa pendekatan StringBuilder hanya sedikit lebih lambat daripada penggabungan String menggunakan operator + .
file: StringTest.java
Perintah Shell: (kompilasi dan jalankan StringTest 5 kali)
Hasil:
sumber
String.format()
lebih dari sekadar senar penggabungan. Misalnya, Anda dapat menampilkan angka di lokal tertentu menggunakanString.format()
.Namun, jika Anda tidak peduli dengan lokalisasi, tidak ada perbedaan fungsional. Mungkin yang satu lebih cepat dari yang lain, tetapi dalam kebanyakan kasus itu akan diabaikan ..
sumber
Secara umum, rangkaian string harus lebih disukai
String.format
. Yang terakhir memiliki dua kelemahan utama:Pada poin 1, maksud saya adalah tidak mungkin untuk memahami apa a
String.format()
panggilan dalam satu kali urutan berurutan. Seseorang dipaksa untuk bolak-balik antara format string dan argumen, sambil menghitung posisi argumen. Untuk penggabungan singkat, ini tidak banyak masalah. Namun dalam kasus ini, penggabungan string kurang verbose.Dengan poin 2, maksud saya bahwa bagian penting dari proses pembangunan dikodekan dalam string format (menggunakan DSL). Menggunakan string untuk mewakili kode memiliki banyak kelemahan. Ini bukan tipe yang aman, dan menyulitkan penyorotan sintaksis, analisis kode, optimisasi, dll.
Tentu saja, ketika menggunakan alat atau kerangka kerja di luar bahasa Jawa, faktor-faktor baru dapat ikut berperan.
sumber
Saya belum melakukan tolok ukur khusus, tetapi saya akan berpikir bahwa rangkaian mungkin lebih cepat. String.format () menciptakan Formatter baru yang, pada gilirannya, menciptakan StringBuilder baru (dengan ukuran hanya 16 karakter). Itu adalah jumlah overhead yang wajar terutama jika Anda memformat string yang lebih panjang dan StringBuilder harus mengubah ukurannya.
Namun, gabungannya kurang bermanfaat dan lebih sulit dibaca. Seperti biasa, ada baiknya melakukan patokan pada kode Anda untuk melihat mana yang lebih baik. Perbedaannya dapat diabaikan di aplikasi server setelah bundel sumber daya Anda, lokal, dll dimuat dalam memori dan kode JITted.
Mungkin sebagai praktik terbaik, itu akan menjadi ide yang baik untuk membuat Formatter Anda sendiri dengan StringBuilder (Appendable) dan Lokal yang berukuran tepat dan menggunakannya dan menggunakannya jika Anda memiliki banyak format yang harus dilakukan.
sumber
Mungkin ada perbedaan yang jelas.
String.format
cukup rumit dan menggunakan ekspresi reguler di bawahnya, jadi jangan biasakan menggunakannya di mana-mana, tetapi hanya jika Anda membutuhkannya.StringBuilder
akan menjadi urutan besarnya lebih cepat (seperti seseorang di sini sudah menunjukkan).sumber
Saya pikir kita bisa mengikuti
MessageFormat.format
karena harus baik pada keterbacaan dan juga aspek kinerja.Saya menggunakan program yang sama yang digunakan oleh Icaro dalam jawaban di atas dan saya meningkatkannya dengan menambahkan kode untuk digunakan
MessageFormat
untuk menjelaskan angka kinerja.PEMBARUAN:
Sesuai Laporan SonarLint, string format printf-style harus digunakan dengan benar (squid: S3457)
Karena
printf-style
format string ditafsirkan pada saat runtime, daripada divalidasi oleh kompiler, mereka dapat mengandung kesalahan yang menghasilkan string yang salah yang sedang dibuat. Aturan ini statis memvalidasi korelasiprintf-style
string format untuk argumen mereka saat memanggil format (...) metodejava.util.Formatter
,java.lang.String
,java.io.PrintStream
,MessageFormat
, danjava.io.PrintWriter
kelas danprintf(...)
metodejava.io.PrintStream
ataujava.io.PrintWriter
kelas.Saya mengganti gaya printf dengan kurung keriting dan saya mendapatkan hasil yang menarik seperti di bawah ini.
Kesimpulan saya:
Seperti yang saya soroti di atas, menggunakan String.format dengan kurung-kurung harus menjadi pilihan yang baik untuk mendapatkan manfaat dari keterbacaan yang baik dan juga kinerja.
sumber
Anda tidak dapat membandingkan String Concatenation dan String.Format oleh program di atas.
Anda dapat mencoba ini juga akan menukar posisi menggunakan String Anda. Kesesuaian dan Penggabungan dalam blok kode Anda seperti di bawah ini
Anda akan terkejut melihat bahwa Format berfungsi lebih cepat di sini. Ini karena objek awal yang dibuat mungkin tidak dirilis dan mungkin ada masalah dengan alokasi memori dan dengan demikian kinerja.
sumber
Dibutuhkan sedikit waktu untuk membiasakan diri dengan String.Format, tetapi itu layak dilakukan pada kebanyakan kasus. Dalam dunia NRA (tidak pernah mengulangi apa pun), sangat berguna untuk menyimpan pesan-pesan token Anda (pencatatan atau pengguna) di pustaka Konstan (saya lebih suka berapa jumlah kelas statis) dan menyebutnya seperlunya dengan String.Format terlepas dari apakah Anda sedang melokalisasi atau tidak. Mencoba menggunakan perpustakaan seperti itu dengan metode penggabungan lebih sulit untuk membaca, memecahkan masalah, mengoreksi, dan mengelola dengan pendekatan apa pun yang memerlukan penggabungan. Penggantian adalah sebuah pilihan, tapi saya ragu itu performant. Setelah bertahun-tahun digunakan, masalah terbesar saya dengan String.Format adalah lamanya panggilan tidak nyaman lama ketika saya meneruskannya ke fungsi lain (seperti Msg), tapi itu mudah untuk disiasati dengan fungsi khusus untuk berfungsi sebagai alias. .
sumber