Vra

Ek het kom oor die volgende tipe van die kode'n baie keer, en ek wonder of dit is'n goeie praktyk (van Prestasie perspektief) of nie:

try
{
    ... // some code
}
catch (Exception ex)
{
    ... // Do something
    throw new CustomException(ex);
}

Basies, wat die kodeerder is om te doen, is dat hulle ook die uitsondering in'n persoonlike uitsondering en gooi dit weer.

Hoe het dit verskil in die Prestasie van die volgende twee:

try
{
    ... // some code
}
catch (Exception ex)
{
    .. // Do something
    throw ex;
}

of

try
{
    ... // some code
}
catch (Exception ex)
{
    .. // Do something
    throw;
}

Sit eenkant enige funksionele of kodering beste praktyk argumente, is daar enige prestasie verskil tussen die 3 benaderings?

Was dit nuttig?

Oplossing

@Brad Tutterow

Die uitsondering is nie verlore in die eerste geval, dit is wat geslaag het in die constructor.Ek sal saam met jou op die res al is, die tweede benadering is'n baie slegte idee as gevolg van die verlies van stapel spoor.Toe ek gewerk het met .NET, ek het in baie gevalle waar ander programmeerders het nie net dat, en dit gefrustreerd my geen einde wanneer ek nodig het om te sien die ware oorsaak van'n uitsondering, net om te vind dat dit rethrown van'n groot probeer blok waar ek nou is het geen idee waar die probleem ontstaan.

Ek het ook tweede Brad se opmerking dat jy nie moet bekommerd wees oor die prestasie.Hierdie soort van mikro optimization is'n VERSKRIKLIKE idee.Tensy jy praat oor gooi'n uitsondering in elke iterasie van'n vir lus wat hardloop vir'n lang tyd, sal jy meer as waarskynlik nie hardloop in die prestasie kwessies deur die pad van jou uitsondering gebruik.

Altyd optimaliseer prestasie wanneer jy statistieke wat daarop dui dat jy NODIG het om te optimaliseer prestasie, en dan tref die kolle wat bewys te wees van die skuldige.

Dit is veel beter om leesbaar kode met'n maklike opsporing vermoëns (dit wil sê nie die wegsteek van die stapel spoor) eerder as iets hardloop'n nano sekonde vinniger.

'n laaste opmerking oor wikkel uitsonderings in'n persoonlike uitsondering...dit kan'n baie nuttig bou, veral wanneer die hantering van UIs.Jy kan draai elke bekend en redelike uitsonderlike geval in sommige basis persoonlike uitsondering (of een wat strek vanaf gesê basis uitsondering), en dan die UI kan net vang hierdie basis uitsondering nie.Wanneer gevang, die uitsondering sal nodig het om te bied middel van die vertoon van inligting aan die gebruiker, sê'n ReadableMessage eiendom, of iets langs die lyne.Dus, enige tyd van die UI mis'n uitsondering nie, dit is as gevolg van'n fout wat jy nodig het op te los, en wanneer dit vang'n uitsondering nie, dit is'n bekende fout toestand wat kan en moet behoorlik hanteer word deur die UI.

Ander wenke

Dit is duidelik dat jy aangaan in die straf van die skep van nuwe voorwerpe (die nuwe uitsondering) so, presies soos jy doen met elke reël van die kode wat jy voeg by jou program, jy moet om te besluit of die beter kategorisering van uitsonderings betaal vir die ekstra werk.

As 'n stuk van die raad om daardie besluit te maak, as jou nuwe voorwerpe nie ekstra inligting is die uitvoering van die uitsondering dan kan jy vergeet die bou van nuwe uitsonderings.

Maar in ander omstandighede, met 'n hiërargie van uitsonderings is baie gerieflik vir die gebruiker van jou klasse. Veronderstel jy die uitvoering van die fasade patroon nie van die tot dusver beskou scenario's is goed:

  1. is nie goed dat jy elke uitsondering in te samel as 'n uitsondering voorwerp omdat jy verloor (waarskynlik) waardevolle inligting
  2. is nie goed nie om elke soort voorwerp wat jy vang, want om dit te doen wat jy versuim is in die skep van die fasade te samel

In hierdie hipotetiese geval, hoe beter ding om te doen is om 'n hiërargie van uitsondering klasse wat, ekserpering jou gebruikers van die innerlike kompleksiteit van die stelsel, hulle toelaat om iets oor die aard van die uitsondering wat weet te skep.

As 'n kant nota:

Ek persoonlik hou nie van die gebruik van uitsonderings (hiërargieë van klasse afgelei van die uitsondering klas) aan logika te implementeer. Soos in die geval:

try {
        // something that will raise an exception almost half the time
} catch( InsufficientFunds e) {
        // Inform the customer is broke
} catch( UnknownAccount e ) {
        // Ask for a new account number
}

Soos Dawid, dink ek dat die tweede en derde beter te presteer. Maar sou enige een van die drie swak genoeg om enige tyd om bekommerd te wees oor dit spandeer voer? Ek dink daar is groter probleme as prestasie te bekommer nie.

FxCop beveel altyd die derde benadering oor die tweede sodat die oorspronklike stapel spoor nie verlore gaan nie.

wysig. Verwyder dinge wat was net plain verkeerd en Mike was gaaf genoeg om daarop te wys

Moenie doen:

try
{
    // some code
}
catch (Exception ex) { throw ex; }

As dit sal verloor die stapel spoor.

In plaas doen:

try
{
    // some code
}
catch (Exception ex) { throw; }

Net die gooi sal doen, jy net nodig het om die uitsondering veranderlike slaag as jy wil hê dit moet die innerlike uitsondering op 'n nuwe persoonlike uitsondering wees.

Soos ander het gesê, die beste prestasie kom uit die onderste een sedert jy net rethrowing 'n bestaande voorwerp. Die middelste een is minstens korrek omdat dit die stapel verloor.

Ek persoonlik gebruik persoonlike uitsonderings as ek wil sekere afhanklikhede ontkoppel in kode. Byvoorbeeld, ek het 'n metode wat data laai van 'n XML-lêer. Dit kan verkeerd gaan in baie verskillende maniere.

Dit kan nie lees van die skyf (FileIOException), kan die gebruiker probeer om dit te bekom van iewers waar hulle nie toegelaat word (SecurityException), kan die lêer korrupte (XmlParseException) wees, data kan wees in die verkeerde formaat ( DeserialisationException).

In hierdie geval, so sy makliker vir die roeping klas om sin van dit alles sluit, al hierdie uitsonderings rethrow 'n enkele persoonlike uitsondering (FileOperationException) so dit beteken dat die oproeper nie verwysings na System.IO of System.Xml nodig, maar kan nog steeds toegang wat fout deur 'n enum en enige belangrike inligting.

Soos, moenie probeer om iets soos hierdie mikro-optimaliseer, die daad van die gooi van 'n uitsondering op alles is die stadigste ding wat hier gebeur. Die beste verbetering te maak, is om te probeer vermy 'n uitsondering nie.

public bool Load(string filepath)
{
  if (File.Exists(filepath)) //Avoid throwing by checking state
  {
    //Wrap anyways in case something changes between check and operation
    try { .... }
    catch (IOException ioFault) { .... }
    catch (OtherException otherFault) { .... }
    return true; //Inform caller of success
  }
  else { return false; } //Inform caller of failure due to state
}

Die gooi in jou eerste voorbeeld het die oorhoofse van die skepping van 'n nuwe CustomException voorwerp.

Die re-gooi in jou tweede voorbeeld sal 'n uitsondering van tipe Uitsondering gooi.

Die re-gooi in jou derde voorbeeld sal 'n uitsondering van dieselfde tipe wat gegooi is deur jou " 'n paar kode".

gooi

So het die tweede en derde voorbeelde gebruik minder hulpbronne.

Wag .... hoekom doen ons omgee prestasie as 'n uitsondering is gegooi? Tensy ons gebruik uitsonderings as deel van die normale aansoek vloei (wat is WAYYYY teen die beste praktyke).

Ek het net gesien prestasie vereistes met betrekking tot sukses, maar nooit met betrekking tot mislukking.

Van 'n suiwer prestasie stand-punt wat ek sou raai dat die derde geval is die meeste performante. Die ander twee moet 'n stapel-spoor te onttrek en nuwe voorwerpe, wat albei potensieel redelik tydrowend bou.

Dit gesê dat hierdie drie blokke van die kode het baie verskillende (eksterne) gedrag hulle so te vergelyk is soos om te vra of QuickSort is meer doeltreffend as 'n item te voeg tot 'n rooi-swart boom. Dit is nie so belangrik as die keuse van die regte ding om te doen.

Gelisensieer onder: CC-BY-SA met toeskrywing
Nie verbonde aan StackOverflow
scroll top