In dem Abschnitt Wann sollte eine Ausnahme in The Pragmatic Programmer verwendet werden , schreibt das Buch Folgendes anstelle von:
retcode = OK;
if (socket.read(name) != OK) {
retcode = BAD_READ;
}
else {
processName(name);
if (socket.read(address) != OK) {
retcode = BAD_READ;
}
else {
processAddress(address);
if (socket.read(telNo) != OK) {
retcode = BAD_READ;
}
else {
// etc, etc...
}
}
}
return retcode;
, Sie bevorzugen:
retcode = OK;
try {
socket.read(name);
process(name);
socket.read(address);
processAddress(address);
socket.read(telNo);
// etc, etc...
}
catch (IOException e) {
retcode = BAD_READ;
Logger.log( "Error reading individual: " + e.getMessage());
}
return retcode;
einfach weil es ordentlicher aussieht. Ich bin alles für saubereren Code, aber ist das unnötige Auffinden von Ausnahmen nicht ein Leistungsengpass?
Ich kann verstehen, dass wir die winzige Optimierung für saubereren Code aufgeben sollten (mindestens 99% der Fälle), aber soweit ich weiß, gehören Ausnahmen zur Codeklasse, die eine merkliche Verzögerung in der Laufzeit haben. Daher habe ich mich gefragt, was die Rechtfertigung dafür ist, dass der zweite Code dem ersten Code vorgezogen wird.
Oder eher, welchen Code würden Sie bevorzugen?
java
exception-handling
language-agnostic
Pacerier
quelle
quelle
Antworten:
Ausnahmen sind normalerweise nur langsamer, wenn sie tatsächlich ausgelöst werden. Normalerweise sind die Ausnahmen in solchen Situationen selten, daher sollten Sie sich keine Sorgen machen. Sie sollten sich nur dann wirklich um die Leistung von Ausnahmen sorgen, wenn diese ständig auftreten und daher ein wichtiger Faktor sind.
Der zweite Code ist besser, weil es viel einfacher ist, der Logik zu folgen. Die Fehlerbehandlung ist gut lokalisiert. Der einzige Einwand ist, dass Sie Ausnahmen verwenden, wenn Sie Ausnahmen verwenden. Fangen Sie die Ausnahmen nicht ab und geben Sie dann einen Fehlercode zurück.
quelle
Nun, wie sie auch sagen, sollten Ausnahmen die Ausnahmefälle behandeln , und da dies ein Ausnahmefall ist (dh etwas, das nur selten vorkommt), würde ich sagen, dass dies auch hier gilt.
Außerdem würde ich raten , gegen Mikro-Optimierung Dinge wie diese. Konzentrieren Sie sich mehr auf die Lesbarkeit des Codes , da Sie viel mehr Zeit mit dem Lesen von Code verbringen als mit dem Schreiben von neuem Code.
Um wirklich sicherzustellen, dass dies ein Leistungsengpass ist, führen Sie eine Profilerstellung durch und analysieren und konzentrieren Sie sich auf die kritischeren Aufgaben, die auf dieser Analyse basieren.
quelle
Woher weißt du das? Wie definieren Sie "spürbare Verzögerung"?
Dies ist genau die Art von vage (und völlig falscher) Leistungsmythos, die zu nutzlosen vorzeitigen Optimierungen führt.
Das Auslösen und Abfangen einer Ausnahme mag im Vergleich zum Hinzufügen von zwei Zahlen langsam sein, ist jedoch im Vergleich zum Lesen von Daten aus einem Socket völlig unbedeutend . Sie könnten wahrscheinlich tausend Ausnahmen auslösen und abfangen, während Sie ein einzelnes Netzwerkpaket gelesen haben. Und wir sprechen hier nicht von Tausenden von Ausnahmen, sondern nur von einer einzigen.
quelle
Ich stimme den Antworten zu, die Sie bereits erhalten haben, dass dies ein Ausnahmefall ist. Daher ist es sinnvoll, die Ausnahmebehandlung zu verwenden.
Wenn Sie Ihre Leistungsprobleme direkter ansprechen, müssen Sie meiner Meinung nach ein Gespür für Skalierbarkeit haben. Das Auslösen / Abfangen einer Ausnahme unter diesen Umständen dauert wahrscheinlich eine Mikrosekunde. Die Flusskontrolle ist langsam - um ein Vielfaches langsamer als normale
if
Aussagen, keine Frage.Denken Sie gleichzeitig daran, dass Sie hier Daten aus einem Netzwerk lesen. Mit 10 Megabit pro Sekunde (langsam für ein lokales Netzwerk, aber ziemlich schnell für Internetverbindungen) entspricht dies der Zeit zum Lesen eines Bytes an Informationen.
Natürlich entsteht dieser Overhead nur, wenn Sie die Ausnahme auch tatsächlich auslösen - wenn er nicht ausgelöst wird, gibt es normalerweise wenig oder gar keinen Overhead (zumindest nach dem, was ich gesehen habe, ist der bedeutendste Overhead nicht von der Ausnahmebehandlung selbst, da mehr potenzielle Kontrollflüsse hinzugefügt werden, was es für den Compiler schwieriger macht, den Code ebenfalls zu optimieren.
In diesem Fall schreiben Sie beim Auslösen einer Ausnahme Daten in das Protokoll. Angesichts der Art der Protokollierung stehen die Chancen gut, dass Sie diese Ausgabe löschen, sobald Sie sie schreiben (um sicherzustellen, dass sie nicht verloren geht). Das Schreiben auf die Festplatte ist (wieder) ein ziemlich langsamer Vorgang - Sie benötigen eine ziemlich schnelle SSD der Enterprise-Klasse, um sogar in den Bereich von Zehntausenden von IOPs / Sekunde zu gelangen. Eine für die Protokollierung verwendete Festplatte kann leicht auf Hunderte von IOPs / Sekunde beschränkt sein.
Fazit: es gibt Fälle , in denen Ausnahmekopf Handhabung kann erheblich sein, aber das ist fast sicher nicht einer von ihnen.
quelle