Python'da istisna işleyicilerin maliyeti


99

Başka bir soruda , kabul edilen cevap, performansı artırmak için Python kodundaki bir (çok ucuz) if ifadesinin bir try / exclu bloğuyla değiştirilmesini önerdi.

Biçim sorunlarını bir kenara kodlamak ve istisnanın asla tetiklenmediğini varsayarsak, bir istisna işleyicisine sahip olmak yerine bir istisna işleyicisine sahip olmak (performans açısından), sıfırla karşılaştırma if ifadesine sahip olmaktan ne kadar fark yaratır?


6
Ölçtüğün zaman ne öğrendin?
S.Lott


Kısım dışında kontrol şansı daha azsa ve eğer şans daha fazla ise, eğer / else'i kullanın.
shadow0359

Yanıtlar:


115

Neden timeitmodülü kullanarak ölçmüyorsunuz ? Bu şekilde, başvurunuzla alakalı olup olmadığını görebilirsiniz.

Tamam, bu yüzden aşağıdakileri denedim:

import timeit

statements=["""\
try:
    b = 10/a
except ZeroDivisionError:
    pass""",
"""\
if a:
    b = 10/a""",
"b = 10/a"]

for a in (1,0):
    for s in statements:
        t = timeit.Timer(stmt=s, setup='a={}'.format(a))
        print("a = {}\n{}".format(a,s))
        print("%.2f usec/pass\n" % (1000000 * t.timeit(number=100000)/100000))

Sonuç:

a = 1
try:
    b = 10/a
except ZeroDivisionError:
    pass
0.25 usec/pass

a = 1
if a:
    b = 10/a
0.29 usec/pass

a = 1
b = 10/a
0.22 usec/pass

a = 0
try:
    b = 10/a
except ZeroDivisionError:
    pass
0.57 usec/pass

a = 0
if a:
    b = 10/a
0.04 usec/pass

a = 0
b = 10/a
ZeroDivisionError: int division or modulo by zero

Dolayısıyla, beklendiği gibi, herhangi bir istisna işleyicisine sahip olmamak biraz daha hızlıdır (ancak istisna gerçekleştiğinde yüzünüzde patlar) ve koşul yerine getirilmediği sürece try/exceptaçıktan daha hızlıdır if.

Ama hepsi aynı büyüklükte ve her iki şekilde de önemli değil. Yalnızca koşul gerçekten karşılanırsa, ifsürüm önemli ölçüde daha hızlıdır.


3
İlginç. Bu yüzden try/exceptdaha hızlıif a != 0
Thilo

12
Ahh, güzel bir kelime seçimi: "hepsi aynı büyüklükte" ... İstisnalardan kaçınan pek çok insanın bunu 10 kat daha yavaş olmasını beklediğinden şüpheleniyorum.
Garrett Bluma

Kodunuzu python 2.7.5 ile Fedora'mda çalıştırmak, "if" sürümünün (0.08 usec / pass), a = 1 olduğunda "dene / hariç" sürümünden (0.11 usec / pass) daha hızlı olduğunu gösteriyor.
duleshi

@duleshi İlginç. Acaba x86 / x64 bir şey mi? Veya belki farklı işlemci uzantıları?
Temel

60

Bu soru aslında Tasarım ve Tarih SSS bölümünde cevaplanmıştır :

Bir dene / hariç bloğu, hiçbir istisna ortaya çıkmazsa son derece etkilidir. Aslında bir istisnayı yakalamak pahalıdır.


3
"Son derece verimli" nin ne kadar verimli olduğunu merak ediyordum. Görünüşe göre çok basit bir "eğer" ifadesinden daha hızlı.
Thilo

Gönderdiğiniz alıntı Tasarım ve Tarih SSS sayfasındadır .
nitsas

Belki "son derece verimli" , Java'da yapılana benzer bir anlama gelir ?
ebk

19

Bu soru yanıltıcıdır. İstisnanın asla tetiklenmediğini varsayarsanız , hiçbiri optimal kod değildir.

İstisnanın bir hata koşulunun bir parçası olarak tetiklendiğini varsayarsanız, zaten en uygun kodu isteme alanının dışındasınızdır (ve muhtemelen onu zaten böyle ince bir düzeyde işlemiyorsunuzdur).

İstisnayı standart kontrol akışının bir parçası olarak kullanıyorsanız - ki bu Pythonic "affetmeyi isteyin, izin değil" yöntemidir - o zaman istisna tetiklenecek ve maliyet istisna türüne, eğer ve istisnanın ne zaman olacağını tahmin ettiğiniz zaman.

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.