Om jag använder fler try - catch och det händer något i den första så den går in i catch, körs de satser som kommer efter då? Ja, om den går in i catch; om någonting fångar felet så är allt ok, felet är hanterat och under kontroll, exekveringen fortsätter efter try-catch-satsen. Tänk också på att dina try-catch tar extra tid att genomföra, speciellt i en loop. Att peppra på med för många är inte effektivt. <b>Tänk också på att dina try-catch tar extra tid att genomföra, speciellt i en loop.</b> Det är inte själva try satsen som tar tid i sig. <b>Tänk också på att dina try-catch tar extra tid att genomföra, speciellt i en loop.</b> >Det talas en del om att try-catch har mycket overhead. Men varför är det så? Är det bara i .Net? Jag kan Det var intressant läsning:) Beror på.. Jag önskade jag hade koll på vart jag läste detta, eller vem som berättade det för mig men jag tror Johan har bevisat det redan - även om det bara var 5000 loopar - det gick ju hälften så fort! ;) Sen är det 1 användare - tänk en webbsajt med 5000 samtidiga användare som gör rutinen samtidigt och många som gör andra rutiner - då börjar det bli lite skillnad som nog är mer mätbar. Enligt en undersökning går är det <b>mindre overhead</b> med undantag än att använda returvärden i PHP5: Nu har jag inte sett specifikt på .net men i c++ fungerar exceptions så här <b>>Även om overheaden för try/catch är miljoner processorinstruktioner (vilket den inte är) så är det ändå inget mot den tid det tar att hämta något från disk/databas/nätverk.</b> Det jag får fram av detta är alltså att jag kan använda try - catch om koden är skriven så det inte smäller. Det är klart att jag försöker skriva kod så det inte ska smälla nån gång, men det går ju inte att förutse allt. >Det jag får fram av detta är alltså att jag kan använda try - catch om koden är skriven så det intetry - catch?
Sv: try - catch?
Sv:try - catch?
Sv: try - catch?
Blev lite nyfiken på om det verkligen var så. Testade därför:
System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
sw.Start();
for (int i = 0; i < 10000; i++)
{
i++;
}
sw.Stop();
MessageBox.Show(sw.ElapsedTicks.ToString());
mot
System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
sw.Start();
for (int i = 0; i < 10000; i++)
{
try
{
i++;
}
catch
{
i--;
}
}
sw.Stop();
MessageBox.Show(sw.ElapsedTicks.ToString());
Första alternativet tar ca 45000 ticks och det andra runt 95000. Det skiljer alltså runt 50000 ticks. Om jag inte räknat fel är det alltså 5 ms. Inte så farligt för 10000 iterationer med andra ord. Eller sker det någon form av optimering här som gör denna jämförelse orättvis? Är lite nyfiken på varför det skulle ge dålig prestanda, har inte läst något om det tidigare.
/Johan
Sv:try - catch?
Det är när det väl smäller så att catchsatsen körs som den stora prestanda hitten uppstår.
Så man ska alltså inte undivka try satser, däremot ska man undvika att ha kod som smäller ;-)Sv: try - catch?
Det talas en del om att try-catch har mycket overhead. Men varför är det så? Är det bara i .Net? Jag kan inte se någon anledning till att det skulle vara jättesegt.Sv:try - catch?
>inte se någon anledning till att det skulle vara jättesegt.
Så länge det inte sker något undantag är overheaden i stort sett obefintlig jämfört med alternativen som t.ex. returkoder. Tänk också på att undantag är något som sker helt internt i programmet (dvs eventuell overhead tar bråkdelar av sekunder) medan det man bevakar oftast har mycket långsammare externa beroenden som disk, nätverk.
Har svårt att se en tillämpning där overhead från try/catch skulle ha någon som helst betydelse för prestanda.Sv: try - catch?
Har det någon betydelse om jag lägger flera anrop i en och samma try - catch?
<code>
try
{
myDB.AddSomething(Object);
myDB.DoSomething(Object);
mail.SendMail(mailObject);
}
catch(Exception ex)
{
lblError.Text = "Det uppstod ett fel: <br />" + ex.Message.ToString();
}
</code>
Eller ska man lägga dom i det här fallet i tre olika satser?Sv:try - catch?
Att lägga dem i samma gör ju så att om någonting fallerar så kommer ju resten inte att exekveras. Att lägga dem i olika gör ju att allting kommer exekveras oavsett om de föregående exekverades. (Om felet hanterades i fall #2 ska tilläggas, i just det här fallet fångas ju alla undantag, men..)
Av den anledningen så kan det ju inte bli ett prestandaskäl. Men om vi struntar i det så borde rimligtvis det vara bättre för prestandan att ha en try-catch än flera, men det lär nog bara vara marginellt..Sv: try - catch?
Det har något med att try-catch måste hålla reda på state på saker och ting. Som i exemplet ovan med en try -catch och 3 rutiner som i sin tur kanske gör samma sak så måste ju rimligen vid starten av programmet massor av pekare hållas reda på, dvs var det smäller, vad värdena är - hur den skall ta sig ur loopen vid fel, vad som skall lagras osv osv osv ...
Om jag drar mig till minnes så var kommentaren så enkel som att om du skriver
try
int y = 8/0
catch
dvs - division by zero ...
så är det ett dåligt sätt att göra det på för att du vet redan vad som kan hända och skall inte hålla på med try catch som hängslen och livrem - där bör du kontrollera att värdena är korrekta istället för att innesluta den med en try/catch. I samma stycke påvisades vad som händer för att hålla reda på ett läge just innan deklarationen vad som gäller.. dvs pekare på värden osv osv - som då tar mycket längre tid än att kanske bara kontrollera om y > 0.
Dock har jag inget klockrent svar på varför - minns bara att det är sagt så... Hihi, flummigt va ;) Finns säkert någon som kan förklara detta bättre med lite fakta bakom sig..Sv:try - catch?
http://jmz.iki.fi/blog/programming/php5_exception_overheadSv:try - catch?
try {
type1 var1(1);
func1();
func2();
}
catch (std::exception& err) {
...
}
Översätts ungefär till (exception är en global variabel som sätts vid throw)
type1 var(1)
if (exception) goto lbl1;
func1()
if (exception) goto lbl2;
func2()
if (exception) goto lbl3;
lbl3:
lbl2:
var.~type1(); // destructor
lbl1:
if (exception) {
// gör en massa jobbiga saker för att reda ut vilken exceptionhandler som skall anropas
}
Inte jättemycket att hålla reda på alltså (och ungefär lika mycket som om man använt returkoder). Det mesta görs redan vid kompileringen så overheaden vid runtime är försumbar.
(För .net blir det dessutom ännu enklare eftersom det inte finns destruktor ordningar att ta hänsyn till)
>tänk en webbsajt med 5000 samtidiga användare som gör rutinen samtidigt och många som gör
>andra rutiner - då börjar det bli lite skillnad som nog är mer mätbar.
Återigen, dessa 5000 användare vill nog ha information som kommer från filsystemet, databasen eller nätverket. Även om overheaden för try/catch är miljoner processorinstruktioner (vilket den inte är) så är det ändå inget mot den tid det tar att hämta något från disk/databas/nätverk.
När det genereras ett undantag så tar det tid. En massa typinformation skall undersökas för att hitta rätt catch. Man skall därför se till att undantag är just det och inte en del av det normala flödet.Sv: try - catch?
För webbapplikationer, förmodligen, men för "riktiga" program i allt mindre utsträckning. Läs http://www.gotw.ca/publications/concurrency-ddj.htm för en bra, om än något gammal, artikel om detta. Herb Sutter är ju ingen lättviktare i det här området...Sv:try - catch?
Sv: try - catch?
>smäller.
Nej, det jag menade var att du skall inte använda catch för att hantera det normala flödet.
Om du skall läsa data i en fil som normalt skall finnas så kan du anväda try/catch för att hantera om filen av någon anledning inte finns, läsfel etc.
Du skall inte använda try catch för att avgöra om filen finns.
Om du gör något annat i catch än att logga/rapportera fel bör du iallafall tänka en extra gång.
Följande är ok
<code>
try {
// öppna fil
// läs fil
// ...
}
catch (Exception) {
// något blev fel
}
</code>
men inte
<code>
try {
// öppna fil
}
catch (Exception) {
// filen fanns inte
// skapa filen
// ...
}
</code>