.NET istisnaları ne kadar yavaştır?


143

Ne zaman istisnalar atmak ve atmamak konusunda tartışmak istemiyorum. Basit bir sorunu çözmek istiyorum. İstisnaları atmama iddiasının% 99'u yavaş yavaş dönerken, diğer taraf (kıyas testi ile) hızın sorun olmadığını iddia ediyor. Bir tarafa veya diğer tarafa ait çok sayıda blog, makale ve yayın okudum. Peki hangisi?

Cevaplardan bazı bağlantılar: Skeet , Mariani , Brumme .


13
yalanlar, lanet yalanlar ve kriterler var. :)
gbjbaanb

Ne yazık ki, burada yüksek oy alan birkaç cevap, sorunun "istisnalar ne kadar yavaş" olduğunu sorduğunu ve özellikle ne sıklıkta kullanılacağı konusundan kaçınmasını istediğini kaçırdı. Aslında sorduğu soruya basit bir cevap ..... Windows CLR'de, istisnalar dönüş değerlerinden 750 kat daha yavaştır.
David Jeske

Yanıtlar:


207

Ben "yavaş değil" tarafında - ya da daha doğrusu "normal kullanımda onlardan kaçınmaya değer yapmak için yeterince yavaş" değilim. Bununla ilgili iki kısa makale yazdım . Kıyaslama yönüyle ilgili eleştiriler vardır, bu da çoğunlukla "gerçek hayatta geçilecek daha fazla yığın olacaktır, bu yüzden önbelleği patlatacaksınız" - ancak yığını yukarı doğru ilerletmek için hata kodlarını kullanmak da önbelleği patlat, bu yüzden bunu özellikle iyi bir argüman olarak görmüyorum.

Sadece açıklığa kavuşturmak için - Mantıksal olmayan istisnaları kullanmayı desteklemiyorum. Örneğin, int.TryParsebir kullanıcıdan veri dönüştürmek için tamamen uygundur. Makine tarafından oluşturulan bir dosyayı okurken uygundur, burada hata "Dosya olması gerektiği formatta değildir, başka neyin yanlış olabileceğini bilmediğim için bunu işlemeyi denemek istemiyorum. "

"Yalnızca makul koşullarda" istisnalar kullanırken, performansı istisnalar nedeniyle önemli ölçüde bozulmuş bir uygulama görmedim. Temel olarak, önemli doğruluk sorunlarınız olmadığı sürece istisnalar sık ​​olmamalıdır ve önemli doğruluk sorunlarınız varsa, performans karşılaştığınız en büyük sorun değildir.


2
ne yazık ki, insanlara istisnaların ücretsiz olduğu söyleniyor, bunları önemsiz 'doğru' işlevsellik için kullanıyorlar, söylediğiniz gibi kullanılmalı, işler yanlış gittiğinde - 'istisnai' koşullarda
gbjbaanb

4
Evet, insanlar istisnaların uygun olmayan şekilde kullanılmasıyla ilişkili bir performans maliyetinin olduğunun farkında olmalıdır. Ben sadece uygun şekilde kullanıldığında bir sorun olduğunu düşünüyorum :)
Jon Skeet

7
@PaulLockwood: Sana başına 200+ istisnalar var eğer söyleyebilirim saniye , sen istisnalar olmana gerek yok. Saniyede 200 kez gerçekleşiyorsa, bu açıkça "istisnai" bir olay değildir. Cevabın son cümlesine dikkat edin: "Temel olarak, önemli doğruluk sorunlarınız olmadığı sürece istisnalar sık ​​sık gerçekleşmemeli ve önemli doğruluk sorunlarınız varsa performans karşılaştığınız en büyük sorun değildir."
Jon Skeet

4
@PaulLockwood: Demek istediğim saniyede 200+ istisnalar, var ise muhtemelen olmasıdır zaten sen istisnalar olmana gerek yok olduğunu gösterir. Çoğu zaman durumun böyle olması beni şaşırtmaz, ancak performans unsurunun ilk endişem olmayacağı anlamına gelir - istisnaların kötüye kullanılması olacaktır. İstisnaların tüm uygunsuz kullanımlarını kaldırdığımda , performansın önemli bir parçası olmasını beklemezdim.
Jon Skeet

4
@DavidJeske: Cevabın noktasını kaçırdınız. Bir istisna atmak, normal bir değer döndürmekten çok daha yavaştır. Kimse bunu tartışmıyor. Soru, çok yavaş olup olmadıklarıdır . Bir istisna atmak için uygun bir durumdaysanız ve bu bir performans sorununa neden oluyorsa, muhtemelen daha büyük sorunlarınız vardır - çünkü sisteminizde büyük miktarda yanlış olduğunu gösterir. Normalde, sorun gerçekten onlar başlamak uygunsuz olduğu zamanlarda istisnaları kullandığınızdan emin olun.
Jon Skeet

31

Bunları uygulayan adamın kesin cevabı var - Chris Brumme. Konu hakkında mükemmel bir blog makalesi yazdı (uyarı - çok uzun) (uyarı2 - çok iyi yazılmış, eğer bir teknisyen iseniz, sonuna kadar okuyacaksınız ve işten sonra saatlerinizi telafi etmeniz gerekiyor :) )

Yönetici özeti: yavaşlar. Win32 SEH istisnaları olarak uygulanırlar, bu yüzden bazıları bile ring 0 CPU sınırını geçecektir! Açıkçası gerçek dünyada, çok fazla iş yapacaksınız, bu yüzden tuhaf istisna hiç fark edilmeyecek, ancak bunları program akışı için kullanırsanız, uygulamanızın çekiçlenmesini bekleyebilirsiniz. Bu, MS pazarlama makinesinin bize bir kötülük yapan başka bir örneğidir. Bir mikrosoftie'yi nasıl tamamen sıfır havai zemine maruz bıraktıklarını söyleyen hatırlıyorum, ki bu tam bir tosh.

Chris uygun bir teklif verir:

Aslında CLR, motorun yönetilmeyen kısımlarında bile dahili olarak istisnalar kullanır. Ancak, istisnalar dışında ciddi bir uzun vadeli performans sorunu vardır ve bu kararınıza dahil edilmelidir.


Bunu, önemli performans sorunları ile sonuçlanan bir "normal program akışıdır" da nullable tipin bir istisnanın defalarca ortaya çıkmasına neden olduğu gerçek dünya testlerinde bundan söz edebilirim . Alwyas, istisnalar istisnai durumlar içindir, aksi takdirde kimseye inanmayın yoksa böyle bir github ipliği ile sonuçlanırsınız!
gbjbaanb

8

İnsanların sadece atıldıklarında yavaş olduklarını söylediklerinde ne hakkında konuştuklarını bilmiyorum.

DÜZENLEME: İstisnalar atılmazsa, bu, yeni İstisna () veya bunun gibi bir şey yaptığınız anlamına gelir. Aksi takdirde istisna, iş parçacığının askıya alınmasına ve yığının yürümesine neden olur. Bu daha küçük durumlarda Tamam olabilir, ancak yüksek trafikli web sitelerinde, bir iş akışı veya yürütme yolu mekanizması olarak istisnalara güvenmek kesinlikle performans sorunlarına neden olacaktır. İstisnalar, kendi başına, kötü değildir ve istisnai koşulları ifade etmek için yararlıdır

Bir .NET uygulamasındaki özel durum iş akışı, birinci ve ikinci şans istisnalarını kullanır. Tüm istisnalar için, onları yakalayıp işliyor olsanız bile, istisna nesnesi hala oluşturulur ve çerçeve hala bir işleyici aramak için yığını yürümelidir. Eğer daha uzun sürecek elbette yakalar ve yeniden düşünürseniz - ilk şans istisnası elde edersiniz, yakalar, geri alırsınız, daha sonra bir işleyici bulamayan başka bir birinci şans istisnasına neden olacaksınız, bu da neden olur ikinci bir şans istisnası.

İstisnalar öbek üzerindeki nesnelerdir - bu nedenle tonlarca istisna atıyorsanız, hem performans hem de bellek sorunlarına neden oluyorsunuz.

Ayrıca, ACE ekibi tarafından yazılan "Performans Testi Microsoft .NET Web Uygulamalarını" kopyasına göre:

"Kural dışı durum işleme pahalıdır. CLR, sağ kural dışı durum işleyiciyi aramak için çağrı yığını aracılığıyla geri çekilirken, konu iş parçacığının yürütülmesi askıya alınır ve bulunduğunda kural dışı durum işleyici ve bazı nihayet blokların yürütme şansı olmalıdır. düzenli işlem yapılmadan önce. "

Alandaki kendi deneyimim, istisnaları azaltmanın performansa önemli ölçüde yardımcı olduğunu gösterdi. Elbette, performans testi yaparken dikkate aldığınız başka şeyler de vardır - örneğin, Disk I / O'nuz çekilirse veya sorgularınız saniyeler içinde ise, o zaman odaklanmanız gerekir. Ancak istisnaları bulmak ve kaldırmak bu stratejinin hayati bir parçası olmalıdır.


1
Yazdığınız hiçbir şey, istisnaların ancak atıldıklarında yavaş olduğu iddiasıyla çelişmez. Sadece onlar durumlar hakkında konuştuk edilir atılmış. İstisnaları kaldırarak "performansa önemli ölçüde yardımcı olduğunuzda": 1) Doğru hata koşulları muydu yoksa yalnızca kullanıcı hatası mıydı?
Jon Skeet

2) Hata ayıklayıcı altında mı çalışıyordunuz, değil mi?
Jon Skeet

Bir istisna ile atmadığınız takdirde yapabileceğiniz tek şey, onu bir nesne olarak yaratmaktır, ki bu anlamsızdır. Hata ayıklayıcının altında olmak ya da olmamak önemli değildir - hala daha yavaş olacaktır. Evet, bağlı bir hata ayıklayıcı ile olacak kancalar var, ama yine de yavaş
Cory Foy

4
Biliyorum - MSFT'deki Premier ekibin bir parçasıydım. :) Diyelim ki bir sürü - gördüğümüz bazı aşırı durumlarda saniyede binlerce. Canlı bir hata ayıklayıcı ile bağlantı kurmak ve sadece istisnaları okuyabildiğiniz kadar hızlı görmek gibi bir şey yok. Ex's yavaş - yani bir DB bağlanıyor, bu yüzden mantıklı olduğunda bunu.
Cory Foy

5
Cory, bence "sadece atıldıklarında yavaşlar", sadece catch / nihayet blokların varlığı nedeniyle performans konusunda endişelenmene gerek yok. Yani bunlar kendi başlarına bir performans vuruşuna neden olmaz, sadece gerçek bir istisna örneğinin ortaya çıkmasına neden olur.
Ian Horwill

6

Anladığım kadarıyla iddia, istisnaları atmanın kötü olmadıklarının kendileri için yavaş olmadıkları değil. Bunun yerine, daha geleneksel koşullu yapılar yerine normal uygulama mantığını kontrol etmenin birinci sınıf yolu olarak throw / catch yapısını kullanmakla ilgilidir.

Genellikle normal uygulama mantığında, aynı eylemin binlerce / milyon kez tekrarlandığı döngü gerçekleştirirsiniz. Bu durumda, bazı çok basit profilleme ile (bkz. Kronometre sınıfına bakın), kendiniz için basit bir if ifadesi yerine bir istisna atmanın oldukça yavaş olabileceğini görebilirsiniz.

Aslında bir keresinde Microsoft'taki .NET ekibinin .NET 2.0'da TryXXXXX yöntemlerini temel FCL türlerinin çoğuna sunduğunu okudum çünkü müşteriler uygulamalarının performansının çok yavaş olduğundan şikayet ediyorlardı.

Birçok durumda bunun nedeni, müşterilerin bir döngüdeki değerlerin tür dönüşümünü denemeye çalışması ve her deneme başarısız olmasıdır. Bir dönüşüm istisnası atıldı ve daha sonra istisnayı yutan ve döngüye devam eden bir istisna işleyici tarafından yakalandı.

Microsoft, bu tür olası performans sorunlarından kaçınmak için özellikle bu durumda TryXXX yöntemlerinin kullanılmasını önerir.

Yanlış olabilirdim, ama okuduğunuz "kıstasların" doğruluğundan emin olmadığınız anlaşılıyor. Basit çözüm: Kendiniz deneyin.


Bu "deneme" işlevlerinin de istisnalar kullandığını düşündüm.
greg

1
Bu "Dene" işlevleri, giriş değerinin Ayrıştırılamaması nedeniyle dahili olarak istisnalar atmaz. Ancak yine de ArgumentException gibi diğer hata durumları için istisnalar atarlar.
Ash

Bu cevabın konunun özüne diğerlerinden daha yakın olduğunu düşünüyorum. 'İstisnaları yalnızca makul koşullarda kullan' demek gerçekten soruyu cevaplamaz - gerçek görüş, kontrol akışı için C # istisnalarının kullanılmasının normal koşullu yapılardan çok daha yavaş olmasıdır. Aksini düşündüğün için affedilebilirsin. OCaml olarak, istisnalar az ya da çok bir GOTO ve uygulanması kabul edilen yoldur mola zorunlu özellikleri kullanırken. Benim özel durumda, sıkı bir döngüde yerini int.Parse () artı deneme / yakalama vs int.TryParse () önemli bir performans artışı vermiştir.
Hugh W

4

XMPP sunucum, sürekli olarak oluşmasını önlemeye çalıştıktan sonra (daha fazla veri okumaya çalışmadan önce bir soketin bağlı olup olmadığını kontrol etmek gibi) ve kendimden kaçınmanın yollarını verdiğimde büyük bir hız artışı (üzgünüm, gerçek sayılar yok, tamamen gözlemsel) kazandı. (belirtilen TryX yöntemleri). Bu sadece yaklaşık 50 aktif (sohbet) sanal kullanıcı ile oldu.


3
Sayılar maalesef faydalı olacaktır :( Soket işlemleri gibi şeyler istisna maliyetlerinden büyük ölçüde ağır basmalıdır, kesinlikle hata ayıklama olmadığında.Tamamen kıyaslama yaparsanız, sonuçları görmek gerçekten çok isterim.
Jon Skeet

3

Sadece bu tartışmaya kendi son deneyimlerimi eklemek için: yukarıda yazılanların çoğuna uygun olarak, hata ayıklayıcı çalışmasa bile, tekrarlanan bir temelde yapıldığında istisnaları son derece yavaş buldum. Beş satır kod değiştirerek yazdığım büyük bir programın performansını% 60 artırdım: istisnalar atmak yerine bir dönüş kodu modeline geçiyorum. Verilen kod binlerce kez çalışıyordu ve ben değiştirmeden önce potansiyel olarak binlerce istisna atıyordu. Bu yüzden yukarıdaki ifadeye katılıyorum: "beklenen" durumlarda uygulama akışını kontrol etmenin bir yolu olarak değil, önemli bir şey gerçekten yanlış gittiğinde istisnalar atın.


2

Onları kodlarla karşılaştırırsanız cehennem kadar yavaşlar. Ancak, önceki posterlerin de belirttiği gibi, normal program işlemine atmak istemezsiniz, bu nedenle sadece bir sorun oluştuğunda ve vakaların büyük çoğunluğunda performans artık önemli değildir (istisna zaten bir yol bloğunu ima ettiği için).

Kesinlikle hata kodları üzerinde kullanılmaya değer, avantajları büyük IMO.


2

İstisnalarla hiç performans problemim olmadı. İstisnaları çok kullanıyorum - eğer yapabilirsem geri dönüş kodlarını kullanmam. Bunlar kötü bir uygulamadır ve bence spagetti kodu gibi kokuyor.

Her şeyin istisnaları nasıl kullandığınıza bağlı olduğunu düşünüyorum: bunları dönüş kodları gibi kullanırsanız (yığıntaki her yöntem çağrısı yakalar ve tekrarlar), evet, yavaş olacaklar, çünkü her bir yakalama / fırlatma yükünüz var.

Ancak yığının altına atarsanız ve tepeden yakalarsanız (bir dönüş kodunun tüm zincirini bir atış / yakalama ile değiştirirseniz), tüm maliyetli işlemler bir kez yapılır.

Günün sonunda geçerli bir dil özelliğidir.

Sadece benim fikrimi kanıtlamak için

Lütfen kodu bu bağlantıda çalıştırın (yanıt için çok büyük).

Bilgisayarımdaki sonuçlar:

marco@sklivvz:~/develop/test$ mono Exceptions.exe | grep PM
10/2/2008 2:53:32 PM
10/2/2008 2:53:42 PM
10/2/2008 2:53:52 PM

Zaman damgaları başlangıçta, dönüş kodları ve istisnalar arasında, sonunda çıkar. Her iki durumda da aynı zaman alır. Optimizasyonlarla derlemeniz gerektiğini unutmayın.


2

Ancak mono, .net bağımsız modundan 10 kat daha hızlı istisna atar ve .net bağımsız modu, .net hata ayıklayıcı modundan 60 kat daha hızlı istisna atar. (Test makineleri aynı CPU modeline sahiptir)

int c = 1000000;
int s = Environment.TickCount;
for (int i = 0; i < c; i++)
{
    try { throw new Exception(); }
    catch { }
}
int d = Environment.TickCount - s;

Console.WriteLine(d + "ms / " + c + " exceptions");

1

Serbest bırakma modunda ek yük minimumdur.

Akış denetimi için istisnaları (örneğin, yerel olmayan çıkışlar) yinelemeli bir şekilde kullanmayacaksanız, farkı fark edebileceğinizden şüpheliyim.


1

Windows CLR'de, bir derinlik-8 çağrı zinciri için, bir istisna atmak bir dönüş değerini kontrol etmek ve yaymaktan 750 kat daha yavaştır. (karşılaştırmalar için aşağıya bakın)

Özel durumlar için bu yüksek maliyet, Windows CLR'nin Windows Yapısal Özel Durum İşleme adı verilen bir şeyle bütünleşmesidir . Bu, istisnaların farklı çalışma zamanlarında ve dillerde düzgün bir şekilde yakalanmasını ve atılmasını sağlar. Ancak, çok çok yavaş.

Mono çalışma zamanında (herhangi bir platformda) istisnalar çok daha hızlıdır, çünkü SEH ile entegre değildir. Bununla birlikte, SEH gibi bir şey kullanmadığı için çoklu çalışma zamanlarında istisnalar geçerken işlevsellik kaybı vardır.

Burada, Windows CLR için istisnalar ve geri dönüş değerleri karşılaştırmalı değerlendirmemden kısaltılmış sonuçlar verilmiştir.

baseline: recurse_depth 8, error_freqeuncy 0 (0), time elapsed 13.0007 ms
baseline: recurse_depth 8, error_freqeuncy 0.25 (0), time elapsed 13.0007 ms
baseline: recurse_depth 8, error_freqeuncy 0.5 (0), time elapsed 13.0008 ms
baseline: recurse_depth 8, error_freqeuncy 0.75 (0), time elapsed 13.0008 ms
baseline: recurse_depth 8, error_freqeuncy 1 (0), time elapsed 14.0008 ms
retval_error: recurse_depth 5, error_freqeuncy 0 (0), time elapsed 13.0008 ms
retval_error: recurse_depth 5, error_freqeuncy 0.25 (249999), time elapsed 14.0008 ms
retval_error: recurse_depth 5, error_freqeuncy 0.5 (499999), time elapsed 16.0009 ms
retval_error: recurse_depth 5, error_freqeuncy 0.75 (999999), time elapsed 16.001 ms
retval_error: recurse_depth 5, error_freqeuncy 1 (999999), time elapsed 16.0009 ms
retval_error: recurse_depth 8, error_freqeuncy 0 (0), time elapsed 20.0011 ms
retval_error: recurse_depth 8, error_freqeuncy 0.25 (249999), time elapsed 21.0012 ms
retval_error: recurse_depth 8, error_freqeuncy 0.5 (499999), time elapsed 24.0014 ms
retval_error: recurse_depth 8, error_freqeuncy 0.75 (999999), time elapsed 24.0014 ms
retval_error: recurse_depth 8, error_freqeuncy 1 (999999), time elapsed 24.0013 ms
exception_error: recurse_depth 8, error_freqeuncy 0 (0), time elapsed 31.0017 ms
exception_error: recurse_depth 8, error_freqeuncy 0.25 (249999), time elapsed 5607.3208     ms
exception_error: recurse_depth 8, error_freqeuncy 0.5 (499999), time elapsed 11172.639  ms
exception_error: recurse_depth 8, error_freqeuncy 0.75 (999999), time elapsed 22297.2753 ms
exception_error: recurse_depth 8, error_freqeuncy 1 (999999), time elapsed 22102.2641 ms

Ve işte kod ..

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1 {

public class TestIt {
    int value;

    public class TestException : Exception { } 

    public int getValue() {
        return value;
    }

    public void reset() {
        value = 0;
    }

    public bool baseline_null(bool shouldfail, int recurse_depth) {
        if (recurse_depth <= 0) {
            return shouldfail;
        } else {
            return baseline_null(shouldfail,recurse_depth-1);
        }
    }

    public bool retval_error(bool shouldfail, int recurse_depth) {
        if (recurse_depth <= 0) {
            if (shouldfail) {
                return false;
            } else {
                return true;
            }
        } else {
            bool nested_error = retval_error(shouldfail,recurse_depth-1);
            if (nested_error) {
                return true;
            } else {
                return false;
            }
        }
    }

    public void exception_error(bool shouldfail, int recurse_depth) {
        if (recurse_depth <= 0) {
            if (shouldfail) {
                throw new TestException();
            }
        } else {
            exception_error(shouldfail,recurse_depth-1);
        }

    }

    public static void Main(String[] args) {
        int i;
        long l;
        TestIt t = new TestIt();
        int failures;

        int ITERATION_COUNT = 1000000;


        // (0) baseline null workload
        for (int recurse_depth = 2; recurse_depth <= 10; recurse_depth+=3) {
            for (float exception_freq = 0.0f; exception_freq <= 1.0f; exception_freq += 0.25f) {            
                int EXCEPTION_MOD = (exception_freq == 0.0f) ? ITERATION_COUNT+1 : (int)(1.0f / exception_freq);            

                failures = 0;
                DateTime start_time = DateTime.Now;
                t.reset();              
                for (i = 1; i < ITERATION_COUNT; i++) {
                    bool shoulderror = (i % EXCEPTION_MOD) == 0;
                    t.baseline_null(shoulderror,recurse_depth);
                }
                double elapsed_time = (DateTime.Now - start_time).TotalMilliseconds;
                Console.WriteLine(
                    String.Format(
                      "baseline: recurse_depth {0}, error_freqeuncy {1} ({2}), time elapsed {3} ms",
                        recurse_depth, exception_freq, failures,elapsed_time));
            }
        }


        // (1) retval_error
        for (int recurse_depth = 2; recurse_depth <= 10; recurse_depth+=3) {
            for (float exception_freq = 0.0f; exception_freq <= 1.0f; exception_freq += 0.25f) {            
                int EXCEPTION_MOD = (exception_freq == 0.0f) ? ITERATION_COUNT+1 : (int)(1.0f / exception_freq);            

                failures = 0;
                DateTime start_time = DateTime.Now;
                t.reset();              
                for (i = 1; i < ITERATION_COUNT; i++) {
                    bool shoulderror = (i % EXCEPTION_MOD) == 0;
                    if (!t.retval_error(shoulderror,recurse_depth)) {
                        failures++;
                    }
                }
                double elapsed_time = (DateTime.Now - start_time).TotalMilliseconds;
                Console.WriteLine(
                    String.Format(
                      "retval_error: recurse_depth {0}, error_freqeuncy {1} ({2}), time elapsed {3} ms",
                        recurse_depth, exception_freq, failures,elapsed_time));
            }
        }

        // (2) exception_error
        for (int recurse_depth = 2; recurse_depth <= 10; recurse_depth+=3) {
            for (float exception_freq = 0.0f; exception_freq <= 1.0f; exception_freq += 0.25f) {            
                int EXCEPTION_MOD = (exception_freq == 0.0f) ? ITERATION_COUNT+1 : (int)(1.0f / exception_freq);            

                failures = 0;
                DateTime start_time = DateTime.Now;
                t.reset();              
                for (i = 1; i < ITERATION_COUNT; i++) {
                    bool shoulderror = (i % EXCEPTION_MOD) == 0;
                    try {
                        t.exception_error(shoulderror,recurse_depth);
                    } catch (TestException e) {
                        failures++;
                    }
                }
                double elapsed_time = (DateTime.Now - start_time).TotalMilliseconds;
                Console.WriteLine(
                    String.Format(
                      "exception_error: recurse_depth {0}, error_freqeuncy {1} ({2}), time elapsed {3} ms",
                        recurse_depth, exception_freq, failures,elapsed_time));         }
        }
    }
}


}

5
Sorunun noktasını kaçırmanın yanı sıra, lütfen DateTime'ı kullanmayın.Şimdi kıyaslamalar için - geçen süreyi ölçmek için tasarlanmış Kronometre'yi kullanın. Burada uzun bir süre ölçtüğünüz için bir sorun olmamalı, ancak alışkanlık haline gelmeye değer.
Jon Skeet

Aksine, soru "istisnalar yavaştır" dönemidir. Özellikle ne zaman istisna atılacağı konusundan kaçınmak istedi, çünkü bu konu gerçekleri gizliyor. İstisnaların performansı nedir?
David Jeske

0

Yakalama istisnaları ile ilgili performans hakkında kısa bir not.

Yürütme yolu bir 'try' bloğuna girdiğinde büyülü bir şey olmaz. 'Deneme' talimatı yoktur ve deneme bloğuna girme veya bu bloktan çıkma maliyeti yoktur. Deneme bloğu hakkındaki bilgiler yöntemin meta verilerinde saklanır ve bu meta veriler bir istisna oluştuğunda çalışma zamanında kullanılır. Yürütme motoru, bir try bloğunda bulunan ilk çağrıyı aramak için yığını aşağı doğru yürür. Kural dışı durum işleme ile ilişkili tüm masraflar yalnızca kural dışı durumlar atıldığında gerçekleşir.


1
Ancak, istisnalar varlığı olabilir açık istisna işleyicilerle yöntemleri satır içi daha zor ve talimat yeniden sıralama onlar tarafından sınırlandırılır - optimizasyonu etkiler.
Eamon Nerbonne

-1

Sınıfları / işlevleri başkalarının kullanması için yazarken, istisnaların uygun olduğunu söylemek zor görünmektedir. BCL'den vazgeçip pinvoke yapmak zorunda kaldığım bazı yararlı bölümleri var, çünkü hataları döndürmek yerine istisnalar atıyorlar. Bazı durumlarda bunun etrafında çalışabilirsiniz, ancak System.Management ve Performans Sayaçları gibi diğerleri için, istisnaların BCL tarafından sık sık atıldığı döngüler yapmanız gereken kullanımlar vardır.

Bir kitaplık yazıyorsanız ve işlevinizin bir döngüde kullanılabilmesi için uzak bir olasılık varsa ve çok sayıda yineleme potansiyeli varsa, Try .. desenini veya istisnaların yanındaki hataları ortaya çıkarmak için başka bir yol kullanın. Ve o zaman bile, paylaşılan ortamdaki birçok işlem tarafından kullanılıyorsa, işlevinizin ne kadar çağrılacağını söylemek zor.

Kendi kodumda, istisnalar sadece işler o kadar olağanüstü olduğunda atılır, yığın izine bakıp neyin yanlış gittiğini görüp düzeltmek gerekir. Bu yüzden, istisnalar yerine Try .. desenine dayalı hata işlemeyi kullanmak için BCL'nin bölümlerini yeniden yazdım.


2
Bu, posterin " Ne zaman ve istisna atmama konusunda bir tartışma istemiyorum " ifadesine uymuyor gibi görünüyor .
hrbrmstr
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.