Di bagian When to Use Exception dalam The Pragmatic Programmer , buku ini menulis bahwa alih-alih:
retcode = OK;
if (socket.read(name) != OK) {
retcode = BAD_READ;
}
else {
processName(name);
if (socket.read(address) != OK) {
retcode = BAD_READ;
}
else {
processAddress(address);
if (socket.read(telNo) != OK) {
retcode = BAD_READ;
}
else {
// etc, etc...
}
}
}
return retcode;
, mereka lebih suka:
retcode = OK;
try {
socket.read(name);
process(name);
socket.read(address);
processAddress(address);
socket.read(telNo);
// etc, etc...
}
catch (IOException e) {
retcode = BAD_READ;
Logger.log( "Error reading individual: " + e.getMessage());
}
return retcode;
hanya karena tampilannya lebih rapi. Aku semua untuk kode lebih rapi, namun tidak perlu menangkap Pengecualian hambatan kinerja?
Saya bisa mengerti bahwa kita harus menyerah optimisasi sangat kecil untuk kode yang lebih rapi (setidaknya 99% dari waktu), namun dari apa yang saya tahu, menangkap pengecualian milik kelas kode yang memiliki keterlambatan nyata dalam runtime. Oleh karena itu saya bertanya-tanya apa pembenaran bahwa potongan kode kedua lebih disukai daripada kode pertama?
Atau lebih tepatnya, kode mana yang Anda inginkan?
java
exception-handling
language-agnostic
Pacerier
sumber
sumber
Jawaban:
Pengecualian biasanya hanya lebih lambat jika mereka benar-benar dilempar. Biasanya, pengecualian dalam situasi seperti ini jarang terjadi sehingga itu bukan sesuatu yang harus Anda khawatirkan. Anda hanya harus benar-benar khawatir tentang kinerja pengecualian jika itu terjadi sepanjang waktu dan dengan demikian merupakan faktor yang signifikan.
Kode kedua lebih baik karena lebih mudah untuk mengikuti logika. Penanganan kesalahan dilokalkan dengan baik. Satu-satunya keberatan adalah bahwa jika Anda menggunakan pengecualian, maka gunakan pengecualian. Jangan menangkap pengecualian dan lalu kembalikan kode kesalahan.
sumber
Yah, seperti yang mereka katakan, pengecualian harus menangani kasus luar biasa , dan karena ini adalah kasus luar biasa (yaitu sesuatu yang terjadi sangat sedikit di antaranya) Saya akan mengatakan bahwa ini berlaku juga di sini.
Juga, saya akan menyarankan agar hal-hal yang tidak mengoptimalkan mikro seperti ini. Lebih fokus pada keterbacaan kode , karena Anda akan menghabiskan lebih banyak waktu membaca kode daripada menulis kode baru.
Untuk benar-benar memastikan bahwa ini adalah hambatan kinerja, lakukan beberapa profil, dan analisis dan fokus pada tugas-tugas yang lebih kritis berdasarkan analisis itu.
sumber
Dari mana Anda tahu itu? Bagaimana Anda mendefinisikan "keterlambatan nyata"?
Ini persis seperti mitos kinerja yang samar-samar (dan sepenuhnya salah) yang mengarah pada optimalisasi prematur yang tidak berguna.
Melempar dan menangkap pengecualian mungkin lambat dibandingkan dengan menambahkan dua angka, tetapi sama sekali tidak signifikan dibandingkan dengan membaca data dari soket. Anda mungkin bisa melempar dan menangkap ribuan pengecualian dalam waktu yang bersamaan Anda membaca satu paket jaringan. Dan kita tidak berbicara tentang ribuan pengecualian di sini, hanya satu pengecualian.
sumber
Saya setuju dengan jawaban yang Anda katakan bahwa ini adalah kasus luar biasa, jadi cukup masuk akal untuk menggunakan penanganan pengecualian.
Mengatasi masalah kinerja Anda secara lebih langsung, saya pikir Anda perlu menjaga skala tentang berbagai hal. Melempar / menangkap pengecualian dalam kondisi ini cenderung mengambil satu urutan mikrodetik. Saat kontrol aliran berjalan, itu lambat - berkali-kali lebih lambat dari
if
pernyataan normal , tidak ada pertanyaan tentang itu.Pada saat yang sama, ingatlah bahwa apa yang Anda lakukan di sini adalah membaca data dari jaringan. Dengan kecepatan 10 megabit per detik (lambat untuk jaringan lokal, tetapi cukup cepat saat koneksi Internet berjalan), itu berada pada urutan yang sama dengan waktu untuk membaca satu byte informasi.
Tentu saja, overhead itu hanya terjadi ketika Anda benar-benar melempar pengecualian - ketika itu tidak dilempar, biasanya ada sedikit atau tidak ada overhead sama sekali (setidaknya dari apa yang saya lihat, overhead yang paling signifikan bukan dari penanganan pengecualian itu sendiri, seperti dari menambahkan lebih banyak potensi aliran kontrol, membuat kode lebih sulit bagi kompiler untuk mengoptimalkan juga)
Dalam hal ini, ketika pengecualian dilemparkan, data tulisan Anda ke log. Mengingat sifat dari pencatatan, kemungkinan Anda cukup bagus untuk mengeluarkannya segera setelah Anda menulisnya (untuk memastikan tidak hilang). Menulis ke disk adalah (sekali lagi) operasi yang cukup lambat - Anda memerlukan SSD kelas enterprise yang cukup cepat bahkan untuk masuk ke kisaran puluhan ribu IOP / detik. Disk yang digunakan untuk logging mungkin dengan mudah dibatasi pada sesuatu seperti ratusan IOP / detik.
Intinya: ada kasus di mana pengecualian menangani overhead bisa menjadi signifikan, tetapi ini hampir pasti bukan salah satu dari mereka.
sumber