Khawatir tentang performa aplikasi web saya, saya bertanya-tanya pernyataan "if / else" atau switch mana yang lebih baik terkait performa?
123
Khawatir tentang performa aplikasi web saya, saya bertanya-tanya pernyataan "if / else" atau switch mana yang lebih baik terkait performa?
if
dll.Jawaban:
Itu adalah pengoptimalan mikro dan pengoptimalan prematur, yang jahat. Agak khawatir tentang keterbacaan dan pemeliharaan kode yang dipermasalahkan. Jika ada lebih dari dua
if/else
balok yang direkatkan atau ukurannya tidak dapat diprediksi, maka Anda mungkin sangat mempertimbangkanswitch
pernyataan.Atau, Anda juga bisa mengambil Polimorfisme . Pertama buat beberapa antarmuka:
Dan dapatkan semua implementasi di beberapa
Map
. Anda dapat melakukan ini baik secara statis atau dinamis:Terakhir, ganti
if/else
atauswitch
dengan sesuatu seperti ini (dengan mengesampingkan pemeriksaan sepele seperti nullpointers):Ini mungkin menjadi microslower dari
if/else
atauswitch
, tetapi kode ini setidaknya jauh lebih baik dipertahankan.Saat Anda berbicara tentang aplikasi web, Anda dapat menggunakan
HttpServletRequest#getPathInfo()
sebagai kunci tindakan (akhirnya menulis beberapa kode lagi untuk memisahkan bagian terakhir dari pathinfo dalam satu lingkaran sampai tindakan ditemukan). Anda dapat menemukan jawaban serupa di sini:Jika Anda mengkhawatirkan kinerja aplikasi web Java EE secara umum, artikel ini juga dapat bermanfaat bagi Anda. Ada area lain yang memberikan lebih banyak keuntungan kinerja daripada hanya (mikro) yang mengoptimalkan kode Java mentah.
sumber
Saya sangat setuju dengan pendapat bahwa pengoptimalan prematur adalah sesuatu yang harus dihindari.
Tetapi memang benar bahwa Java VM memiliki bytecode khusus yang dapat digunakan untuk switch ().
Lihat Spesifikasi WM ( lookupswitch dan tableswitch )
Jadi mungkin ada beberapa peningkatan kinerja, jika kode tersebut merupakan bagian dari grafik CPU kinerja.
sumber
Sangat tidak mungkin bahwa jika / lain atau sakelar akan menjadi sumber penurunan kinerja Anda. Jika Anda mengalami masalah kinerja, Anda harus melakukan analisis profil kinerja terlebih dahulu untuk menentukan di mana titik lambatnya. Optimasi prematur adalah akar dari segala kejahatan!
Namun demikian, dimungkinkan untuk membicarakan kinerja relatif switch vs. if / else dengan pengoptimalan kompilator Java. Catatan pertama bahwa di Java, pernyataan switch beroperasi pada domain yang sangat terbatas - integer. Secara umum, Anda dapat melihat pernyataan switch sebagai berikut:
dimana
c_0
,,c_1
..., danc_N
adalah bilangan integral yang merupakan target pernyataan switch, dan<condition>
harus menyelesaikan ekspresi integer.Jika set ini "padat" - yaitu, (maks (c i ) + 1 - min (c i )) / n> α, di mana 0 <k <α <1, di mana
k
lebih besar dari beberapa nilai empiris, a tabel lompat dapat dibuat, yang sangat efisien.Jika himpunan ini tidak terlalu padat, tetapi n> = β, pohon pencarian biner dapat menemukan target dalam O (2 * log (n)) yang juga masih efisien.
Untuk semua kasus lainnya, pernyataan switch sama efisiennya dengan rangkaian pernyataan if / else yang setara. Nilai yang tepat dari α dan β bergantung pada sejumlah faktor dan ditentukan oleh modul pengoptimalan kode penyusun.
Akhirnya, tentu saja, jika domain dari
<condition>
bukan bilangan bulat, pernyataan switch sama sekali tidak berguna.sumber
Gunakan saklar!
Saya benci mempertahankan blok if-else-! Lakukan tes:
Kode standar C # saya untuk pembandingan
sumber
switch
es itu?Saya ingat pernah membaca bahwa ada 2 jenis pernyataan Switch di bytecode Java. (Saya pikir itu di 'Java Performance Tuning' One adalah implementasi yang sangat cepat yang menggunakan nilai integer pernyataan switch untuk mengetahui offset kode yang akan dieksekusi. Ini akan membutuhkan semua integer untuk berurutan dan dalam kisaran yang terdefinisi dengan baik Saya menduga bahwa menggunakan semua nilai Enum akan termasuk dalam kategori itu juga.
Saya setuju dengan banyak poster lain ... mungkin terlalu dini untuk mengkhawatirkan hal ini, kecuali ini adalah kode yang sangat panas.
sumber
switch
beberapa cara berbeda, beberapa lebih efisien daripada yang lain. Secara umum, efisiensinya tidak lebih buruk daripada "if
tangga" lurus ke depan , tetapi ada cukup banyak variasi (terutama dengan JITC) sehingga sulit untuk lebih tepat dari itu.Menurut Cliff Click dalam bukunya Java One talk 2009 A Crash Course in Modern Hardware :
Anda bisa mendapatkan slide lengkapnya di sini .
Cliff memberi contoh (menyelesaikan Slide 30) yang menunjukkan bahwa meskipun CPU melakukan penggantian nama register, prediksi cabang, dan eksekusi spekulatif, ia hanya dapat memulai 7 operasi dalam 4 siklus jam sebelum harus memblokir karena dua cache yang meleset. 300 siklus jam untuk kembali.
Jadi dia mengatakan untuk mempercepat program Anda, Anda seharusnya tidak melihat masalah kecil seperti ini, tetapi pada masalah yang lebih besar seperti apakah Anda membuat konversi format data yang tidak perlu, seperti mengonversi "SOAP → XML → DOM → SQL →… "yang" melewatkan semua data melalui cache ".
sumber
Dalam pengujian saya, kinerja yang lebih baik adalah ENUM> MAP> SWITCH> IF / ELSE IF di Windows7.
sumber
Time taken for String in Switch :3235 Time taken for String in if/else if :3143 Time taken for String in Map :4194 Time taken for String in ENUM :2866
Untuk sebagian besar
switch
dan sebagian besarif-then-else
blok, saya tidak dapat membayangkan bahwa ada masalah terkait kinerja yang cukup berarti atau signifikan.Tapi inilah masalahnya: jika Anda menggunakan
switch
blok, penggunaannya menunjukkan bahwa Anda mengaktifkan nilai yang diambil dari sekumpulan konstanta yang diketahui pada waktu kompilasi. Dalam kasus ini, Anda seharusnya tidak menggunakanswitch
pernyataan sama sekali jika Anda dapat menggunakanenum
dengan konstanta spesifik.Dibandingkan dengan
switch
pernyataan, enum memberikan keamanan tipe dan kode yang lebih baik yang lebih mudah dipelihara. Enum dapat dirancang sehingga jika sebuah konstanta ditambahkan ke himpunan konstanta, kode Anda tidak akan dikompilasi tanpa menyediakan metode spesifik-konstanta untuk nilai baru. Di sisi lain, lupa menambahkan yang barucase
ke sebuahswitch
blok terkadang hanya dapat ditangkap pada waktu proses jika Anda cukup beruntung untuk mengatur blok Anda untuk membuat pengecualian.Performa antara
switch
danenum
metode spesifik-konstan seharusnya tidak jauh berbeda, tetapi metode terakhir lebih mudah dibaca, lebih aman, dan lebih mudah dikelola.sumber