try and catch - verlangsamt?
-
Heiho
Heute habe ich mal wieder festgestellt das ich zu selten try & catch verwende, dazu haette ich eine frage
macht es sinn viele try throw catch bloecke zu haben?
wennn man "viele" hatt, verlangsamt das die laufzeit?gibt es eine art "leitfaden" wann ein try throw sinn macht?
danke schonmal
-
Das ist Imlementierungsabhängig. Normalerweise ist ein try billiger als ein explizites if. Laut Bjarne Stroustrup sollte es bei try ohne eine geworfenen Ausnahme sogar einen Performancevorteil geben. (müsste ich nochmal in seinem Buch nachschlagen)
Beispiel, bei dem kein Fehler/Ausnahme auftritt:
if( foo() != OK ) { error("Falsch!"); }try { foo(); }catch(...) { error("Falsch!"); }Naja, in der ersten Variante macht man IMMER einer if-Abfrage. Du verschwendest auf jeden Fall Performance, selbst wenn es eine Mio. mal nie zu einem Fehler kommt. In der zweiten Variante wird, wenn nie eine Exception von foo geworfen wird, keine Taktzyklen verbraten. Aber wenn doch einmal, wird es etwas langsamer.
Naja, das ist die Theorie, wobei 1. Variante definitiv stimmt. 2. Variante ist Implementierungsabhängig.
Wenn du ne Software entwickelst, wo es auf jeden Taktzyklus ankommt, mußt du testen. Wenn der Taktzyklus an der Stelle nicht wichtig ist, würde ich immer Exceptions nehmen.
-
Mr Evil, mach dir mal um die Laufzeit keine Gedanken

Zur Frage "macht es sinn viele try throw catch bloecke zu haben?": naja, ein "throw" macht dort Sinn wo es "hingehört", und ein "try-catch" genauso.

Beispiel: an vielen Stellen macht es z.B. keinen Sinn Parameter ala "if (!gueltig) throw xxx();" zu überprüfen, meistens ist es besser einfach "assert(gueltig);" reinzuschreiben.
Natürlich gibt es auch viele Stellen wo es Sinn macht Werte/Parameter zu validieren, z.B. wenn ein Wert aus einem File kommt, über eine Netzwerkverbindung, oder gar von einem User eingegeben wurde, dann muss man den validieren. Hier können in vielen Fällen Exceptions "angebracht" sein, allerdings nicht notwendigerweise, manchmal ist auch ne "if-return" Lösung besser - allgemeine Regel kann ich da im Moment leider keine formulieren. Ein anderes Beispiel wo ich immer Parameter validiere sind APIs die wir implementieren und die die Firma verlassen, z.B. mit denen Kunden von uns arbeiten.Allgemein: wenn ich irgendeinen Vorgang habe, der "eigentlich immer hinhauen muss", wo die API die ich verwende aber Fehlercodes zurückgibt (z.B. das Öffnen eines Datenfiles welches mit dem Programm "mitinstalliert" wird), dann muss ich das irgendwie handlen. Wenn das Programm ohne diesen Vorgang (um das Beispiel weiterzufürhen: ohne das erfolgreiche Öffnen des Datenfiles) überhaupt nicht sinnvoll arbeiten kann, dann braucht man weder Exceptions noch Returncodes, dann kann man einfach ne Meldung ausgeben und das Programm dann abbrechen (terminate()). Wenn man das Programm ohne diesen Vorgang (z.B. wieder: Öffnen der Datei) auch noch einfach fortsetzen kann (vielleicht nur mit eingeschränktem Funktionsumfang), dann sollte es auch weiterlaufen, bloss muss man den Fehler trotzdem irgendwie behandeln. Und da verwende ich persönlich wieder meistens Exceptions, da es meistens das einfachste ist.
Angenommen ich möchte eine Rechtschreibprüfung durchführen, dann können dort einige Dinge schiefgehen, darunter das Öffnen des Files wo die bekannten Wörter drinnen stehen aber genauso Speicheranforderungen etc. In so einem Fall habe ich dann mehrere Stellen wo ein "throw" stehen kann, aber meistens nur ein einziges "try-catch", da es ziemlich egal ist WAS schiefgegangen ist, das Resultat ist immer "kann Rechtschreibprüfung nicht durchführen". Demzufolge steht das "try-catch" auch in der "DoSpellCheck()" Funktion. Im "catch" sieht man sich die Exception an und bastelt eine geeignete Fehlermeldung zusammen, zeitgt die an, fertig.
----
Phui. Viel geschrieben, ich hoffe du kannst damit was anfangen.
Sers.
-
@Artchi:
Ein "if" vs. ein "try-catch" ist wohl ein Vergleich der AFAIK leicht zugunsten des "if" ausgehen kann. Bloss dass auf ein "try-catch" oft mehr als nur ein "if" kommt welches wegfällt, können leicht mal 10 oder mehr sein -- man muss ja nicht in jeder Funktion ein "try-catch" stehen haben, oft ist das nur an vergleichweise wenigen Stellen nötig bzw. sinnvoll.
Und dann sieht die Sache schon wieder besser aus für Exceptions...
-
hustbaer schrieb:
...Wenn das Programm ohne diesen Vorgang ...überhaupt nicht sinnvoll arbeiten kann,...
Auch, wenn ich dem prinzipiell zustimme, sehe ich das Problem darin, dass diese Unterscheidung nur sehr selten wirklich zu treffen ist. Das liegt vA am OOP und ReUse:
Wenn ich eine Klasse schreibe, weiß ich oft nicht, ob sie in einem kleinen Utility mit menschlichem Benutzer davor oder in einem multithreaded Server mit zahllosen Ressourcenbindungen genutzt wird. Wenn ich Letzteren einfach runterreiße, kann das einen Haufen Ärger verursachen ...Da überlasse ich diese Entscheidung lieber dem Nutzer meiner Klasse, indem ich exceptions werfe: In einem "simpel-PG" kümmert sich keiner drum und unexpected-terminate-abort zündet (wie bei assert()). Aber ein "Serverschreiber" kann mit einen try/catch (am Besten im "Thread-Main()") das Teil abfangen und vielleicht noch etwas retten...
Klar - jetzt kann das Argument kommen: "Ja - dafür macht man doch die Tests", aber warum sollte man sich allein auf dieses dünne Brett (das in der Realität oft sehr brüchig ist) verlassen ?
Und selbst diese Entscheidung überlasse ich dem Nutzer.
Gruß,
Simon2.
-
Ja, wenn man Komponenten schreibt ist das schon OK wenn man in so Situationen wo kein (Programmier-)Fehler vorliegt sondern bloss irgendwas anderes "danebengegangen" ist eine Exception wirft.
Wenn ich aber eine Applikation schreibe passe ich in Code der IMHO sowieso nicht wiederverwendbar ist nicht unbedingt darauf auf.
-
ich glaube, das gibt sich bei if recht wenig...
aber zb bei schleifen ist es wahrscheinlich doch was langsamer, wenn bei jeden durchlauf die abbruchbedingung geprüft wird, oder?