1. Gambaran keseluruhan
Dalam artikel pendek ini, kita akan melihat persamaan dan perbezaan antara StringBuilder dan StringBuffer di Java.
Secara sederhana , StringBuilder diperkenalkan di Java 1.5 sebagai pengganti StringBuffer .
2. Persamaan
Kedua StringBuilder dan StringBuffer membuat objek yang memegang urutan watak yang boleh berubah. Mari lihat bagaimana ini berfungsi, dan bagaimana ia dibandingkan dengan kelas String yang tidak berubah :
String immutable = "abc"; immutable = immutable + "def";
Walaupun kelihatan seperti kita mengubah objek yang sama dengan menambahkan "def" , kita membuat yang baru kerana instance String tidak dapat diubah.
Apabila menggunakan StringBuffer atau StringBuilder, kita boleh menggunakan kaedah append () :
StringBuffer sb = new StringBuffer("abc"); sb.append("def");
Dalam kes ini, tidak ada objek baru yang dibuat. Kami telah memanggil kaedah append () pada instance sb dan mengubah kandungannya. StringBuffer dan StringBuilder adalah objek yang boleh berubah.
3. Perbezaan
StringBuffer disegerakkan dan oleh itu selamat di dalam benang. StringBuilder serasi dengan StringBuffer API tetapi tanpa jaminan penyegerakan.
Kerana ia bukan implementasi yang selamat untuk utas, lebih cepat dan disarankan untuk menggunakannya di tempat yang tidak memerlukan keselamatan benang.
3.1. Persembahan
Dalam lelaran kecil, perbezaan prestasi tidak signifikan. Mari buat penanda aras mikro cepat dengan JMH:
@State(Scope.Benchmark) public static class MyState { int iterations = 1000; String initial = "abc"; String suffix = "def"; } @Benchmark public StringBuffer benchmarkStringBuffer(MyState state) { StringBuffer stringBuffer = new StringBuffer(state.initial); for (int i = 0; i < state.iterations; i++) { stringBuffer.append(state.suffix); } return stringBuffer; } @Benchmark public StringBuilder benchmarkStringBuilder(MyState state) { StringBuilder stringBuilder = new StringBuilder(state.initial); for (int i = 0; i < state.iterations; i++) { stringBuilder.append(state.suffix); } return stringBuilder; }
Kami telah menggunakan mod Throughput lalai - iaitu operasi per unit masa (skor yang lebih tinggi lebih baik), yang memberikan:
Benchmark Mode Cnt Score Error Units StringBufferStringBuilder.benchmarkStringBuffer thrpt 200 86169.834 ± 972.477 ops/s StringBufferStringBuilder.benchmarkStringBuilder thrpt 200 91076.952 ± 2818.028 ops/s
Sekiranya kita meningkatkan bilangan lelaran dari 1k hingga 1m maka kita mendapat:
Benchmark Mode Cnt Score Error Units StringBufferStringBuilder.benchmarkStringBuffer thrpt 200 77.178 ± 0.898 ops/s StringBufferStringBuilder.benchmarkStringBuilder thrpt 200 85.769 ± 1.966 ops/s
Walau bagaimanapun, ingatlah bahawa ini adalah penanda aras mikro, yang mungkin atau mungkin tidak memberi kesan yang nyata terhadap prestasi sebenar aplikasi dunia nyata.
4. Kesimpulan
Ringkasnya, StringBuffer adalah pelaksanaan yang selamat untuk benang dan oleh itu lebih perlahan daripada StringBuilder .
Dalam program utas tunggal, kita dapat memanfaatkan StringBuilder . Namun, peningkatan prestasi StringBuilder berbanding StringBuffer mungkin terlalu kecil untuk membenarkan menggantikannya di mana sahaja. Adalah idea yang baik untuk profil aplikasi dan memahami ciri-ciri prestasi masa operasinya sebelum melakukan apa-apa kerja untuk menggantikan satu pelaksanaan dengan yang lain.
Akhirnya, seperti biasa, kod yang digunakan semasa perbincangan boleh didapati di GitHub.