Okunabilirliği artırmak için “istisnaları yakalamak” mı, İyi mi Kötü mü?


9

Bölümde Kullanım Exception içinde Pragmatik Programcı , kitap yazma yerine o:

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;

, onlar tercih eder:

 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;

çünkü daha temiz görünüyor. Ben bütün Ancak bir performans darboğazı İstisnalar yakalamak gereksiz değildir, daha düzgün kod için?

Ben yiyen kodu (zamanların en az% 99) için minik optimizasyon vazgeçmek gerektiğini anlıyorum, ancak bildiğim kadarıyla, yakalama istisnaları çalışma zamanında belirgin bir gecikme olan kod sınıfına aittir. Bu nedenle, ikinci kod parçasının ilk kod yerine tercih edilmesinin gerekçesi olduğunu merak ediyordum.

Daha doğrusu, hangi kodu tercih edersiniz?


kod inceleme sorusu değil, en iyi uygulama sorusu olduğu için Code Review'dan taşındı
Winston Ewert

1
IMO, sen bekliyoruz soket gelenler valuse okumak edebilmek için, daha sonra bir ioEx olan olağanüstü.
Steven Evers


Ölçtün mü?

@ ThorbjørnRavnAndersen Tabii ki kitabı okuyordum ve ölçmek için gerçek bir "test vakası" yok .. ama
anlaşmalı bir kodda ölçersek,

Yanıtlar:


18

İstisnalar genellikle sadece gerçekten atıldıklarında daha yavaştır. Genellikle, bu gibi durumlarda istisnalar nadirdir, bu yüzden endişelenmeniz gereken bir şey değildir. İstisnaların performansı hakkında gerçekten her zaman oluyorlarsa ve bu nedenle önemli bir faktörse gerçekten endişelenmelisiniz.

İkinci kod daha iyidir çünkü mantığı takip etmek çok daha kolaydır. Hata işleme güzel bir şekilde yerelleştirilmiştir. Tek itiraz, istisnalar kullanıyorsanız istisnalar kullanmaktır. İstisnaları yakalamayın ve ardından bir hata kodu döndürün.


4
Kabul ediyorum, istisnaları olan bir dilde hata kodlarını görmekten nefret ediyorum. Eğer, rethrow, yakalamak giriş yapmalıdır Çoğu zaman olmadan çağrı yığını kesiliyor. Ve çoğu zaman, bir "istisna" durumunun daha yavaş olması önemli değildir. Uygulamanın bir sorunu var, düzgün işlemek için zaman ayırın. İstisna istisnai olduğu ve uygulamanın normal çalışmasının veya mutlu yolunun bir parçası olmadığı sürece, genellikle bir kod kokusu değildir.
CaffGeek

Btw biz datastreams kullandığı hattın son algılamak için EOFException haklı nasıl merak ediyorum (yolun sonu olağanüstü değil öyle) 'de gösterildiği gibi docs.oracle.com/javase/tutorial/essential/io/datastreams.html ?
Pacerier

@ Pacer, olağanüstü olabilir. Satırdaki girdinin tükenmesi, kötü verilerin veya korkunç bir şekilde yanlış giden bir şeyin olduğunu gösterebilir. Amaçlanan kullanımın birkaç alanı bir satırdan ayrıştırmak olduğundan şüpheleniyorum.
Winston Ewert

@Downvoter, cevap ile ilgili bir sorununuz varsa, lütfen açıklayın!
Winston Ewert

5

Dedikleri gibi, istisnalar istisnai durumları ele almalıdır ve bu istisnai bir durum olduğu için (yani aralarında çok az şey olan bir şey) bunun da burada geçerli olduğunu söyleyebilirim.

Ayrıca, bu gibi mikro optimizasyon şeylerine karşı tavsiye ediyorum . Yeni kod yazmaktan çok daha fazla zaman harcayacağınızdan , kodun okunabilirliğine daha fazla odaklanın .

Bunun bir performans darboğazı olduğundan emin olmak için, biraz profilleme yapın ve bu analize dayanan daha kritik görevleri analiz edin ve odaklanın.


5

Ben yiyen kodu (zamanların en az% 99) için minik optimizasyon vazgeçmek gerektiğini anlıyorum, ancak bildiğim kadarıyla, yakalama istisnaları çalışma zamanında belirgin bir gecikme olan kod sınıfına aittir.

Bunu nereden biliyorsun? "Fark edilebilir gecikmeyi" nasıl tanımlıyorsunuz?

Bu tam olarak işe yaramaz erken optimizasyonlara yol açan belirsiz (ve tamamen yanlış) performans mitidir.

Bir istisna atmak ve yakalamak iki sayı eklemeye kıyasla yavaş olabilir, ancak bir soketten veri okumakla karşılaştırıldığında tamamen önemsizdir . Tek bir ağ paketini okuduğunuzda muhtemelen bin istisna atabilir ve yakalayabilirsiniz. Ve burada binlerce istisnadan bahsetmiyoruz, sadece tek bir istisna.


Ben .NET gelen Java bilgim af yüzden, ama ben şahsen "kod-istisna yakalama" kaldırarak sabitlendi deli gecikmeleri (saniye büyüklüğü) neden .NET içinde durumları yakalamak .. yaşamış
Pacerier

@ Pacer, cidden mi? saniye büyüklüğü? Sanırım belki bir sürü istisna yakalamıştı? Sonra görebiliyordum.
Winston Ewert

3
@Pacerier: İstisnalar deli gecikmelere neden oluyorsa, bunlara neden olan şey açıkça istisnai değildir ve bu nedenle başka şekillerde ele alınmalıdır. Hiçbir sistemin bir istisnayı işlemesi birkaç saniye sürmemelidir ve bence Microsoft bundan kaçınmak için yeterince yetkin.
David Thornley

5

Bunun istisnai bir durum olduğunu söylediğiniz cevaplara katılıyorum, bu yüzden istisna işleme kullanmak makul olabilir.

Performans endişelerinizi daha doğrudan ele almak için, bence şeyler hakkında ölçek duygusu tutmanız gerekiyor. Bu koşullar altında bir istisna atmak / yakalamak bir mikrosaniye sırasını alacaktır. Akış kontrolü ilerledikçe, bu yavaştır - normal ififadelerden birçok kez daha yavaştır , bu konuda bir soru yoktur.

Aynı zamanda, burada yaptığınız şeyin bir ağdan veri okumak olduğunu unutmayın. Saniyede 10 megabitte (yerel bir ağ için yavaş, ancak İnternet bağlantıları ilerledikçe oldukça hızlı), bu bir bayt bilgi okuma zamanı ile aynı sıradadır .

Tabii ki, bu ek yük sadece istisnayı gerçekten attığınızda gerçekleşir - atılmadığında, genellikle çok az veya hiç ek yük yoktur (en azından gördüğümden, en önemli ek yük, daha fazla potansiyel kontrol akışı ekleyerek, derleyicinin de kodu optimize etmesini zorlaştırdığı için istisna işleme).

Bu durumda, bir istisna atıldığında, verilerinize günlüğe yazılır. Günlüğe kaydetmenin doğası göz önüne alındığında, yazdığınız anda çıktıyı yıkamanız (kaybolmamasını sağlamak için) oldukça iyidir. Diske yazmak (tekrar) oldukça yavaş bir işlemdir - on binlerce IOP / saniye aralığına bile girmek için oldukça hızlı bir işletme sınıfı SSD'ye ihtiyacınız vardır. Günlüğe kaydetmek için kullanılan bir disk yüzlerce IOP / saniye gibi bir şeyle kolayca sınırlandırılabilir.

Alt satır: istisna işleme yükünün önemli olabileceği durumlar vardır , ancak bu neredeyse kesinlikle bunlardan biri değildir .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.