Was ist schneller, versuche catch oder if-else in java (WRT-Leistung)
Welche ist schneller:
Entweder diese
try {
n.foo();
}
catch(NullPointerException ex) {
}
oder
if (n != null) n.foo();
InformationsquelleAutor der Frage Rakesh | 2010-08-16
Du musst angemeldet sein, um einen Kommentar abzugeben.
Es ist nicht die Frage, welche schneller ist, sondern eine der Richtigkeit.
Eine Ausnahme ist für die Umstände, die sind genau das, außergewöhnliche.
Ob es möglich ist für
n
zunull
als Teil der normalen Geschäftslogik, dann verwenden Sie einif..else
sonstthrow
eine Ausnahme.InformationsquelleAutor der Antwort Mitch Wheat
ist schneller.
InformationsquelleAutor der Antwort Boris Pavlović
Explizit testen für ein null-Zeiger ist viel schneller als die Verwendung der Ausnahmebehandlung.
Für die Aufzeichnung, die meisten der oherheads in mit Ausnahmen entstehen in der Instanziierung des exception-Objekts. Insbesondere im Aufruf zu
fillInStackTrace()
hat:In einigen Fällen können Sie reduzieren durch Wiederverwendung des exception-Objekts oder durch das überschreiben eine anwendungsspezifische Ausnahme
fillInStackTrace()
Methode zu machen, ein no-op. Der Nachteil in beiden Fällen ist, dass eine ordnungsgemäße stacktraces nicht mehr zur Verfügung, um Ihnen zu helfen debug unerwartete Ausnahmen. (Und keines dieser gelten für die OP ' s-Beispiel.)Während Ausnahme Instanziierung teuer ist, exception werfen, Fortpflanzung und Fang sind nicht ganz Billig.
Gibt es einen zweiten Grund, warum explizite null-Test ist eine bessere Idee. Bedenken Sie:
Was passiert, wenn eine NPE passiert im Aufruf
doSomething(...)
statt bei der Auswertung dera.field
Ausdruck? Sicher, wir kriegen eine NPE, aber wir werden misdiagnose es, und dann versuchen, weiter ... falsch unter der Annahme, dassa.field
ist nicht gesetzt oder so etwas.Unterscheidung eines "erwarteten" NPE von einer "unerwarteten" NPE ist theoretisch möglich, aber in der Praxis sehr schwierig. Ein einfacher und robuster Ansatz ist der explizite test für die
null
Werte, die Sie erwarten (z.B. mit einemif
- Anweisung), und behandeln alle NPEs als Fehler.(Ich bin mir sicher, dass dies ist, was @Mitch bedeutet, durch "behandeln von Ausnahmen wie außergewöhnlich", aber ich denke, es hilft, zu buchstabieren, Dinge mit einem illustrativen Beispiel ...)
InformationsquelleAutor der Antwort Stephen C
Die Antwort ist nicht so einfach, wie es aussieht, weil das hängt davon ab, auf den Prozentsatz von Zeiten, dass das Objekt wirklich null. Wenn dies sehr selten ist (etwa in 0,1% der Zeit), könnte es sogar schneller sein. Um dies zu testen habe ich einige gemacht benchmarking mit den folgenden Ergebnissen (mit Java 1.6-client):
Scheint dies ziemlich schlüssig für mich. NPE ' s sind nur sehr langsam. (Ich kann nach der Benchmark-code, falls gewünscht)
Bearbeiten:
Ich habe gerade eine interessante Entdeckung gemacht: wenn benchmarking mit der server-JVM, die Ergebnisse ändern sich drastisch:
Verwendung der server-VM, der Unterschied ist kaum bemerkbar. Trotzdem: würde ich eher nicht verwenden, fangen NullPointerException, es sei denn, es ist wirklich eine Ausnahme.
InformationsquelleAutor der Antwort Marc
Wenn
n.foo()
passiert zu werfen, intern eine NPE, Sie sind für eine lange debugging-session (oder noch schlimmer, Ihre app nicht in Produktion..). Nur tun Sie es nicht.Wie viele nano-Sekunden machen Sie plan zu speichern, sowieso?
InformationsquelleAutor der Antwort Enno Shioji
Ich merke, ich bin nicht der einzige, der das Lesen der Java-Spezialist Newsletter 🙂
Abgesehen von der Tatsache, dass es eine semantischen Unterschied (die NPE ist nicht unbedingt verursacht durch dereferenzieren
n
es gewesen sein könnte, ausgelöst durch einige Fehler infoo()
), und eine Lesbarkeit Problem (try/catch ist mehr verwirrend für die Leser als dieif
), Sie sollte etwa gleich schnell sind in dem Fall, wennn != null
(mit if/else " - version mit einem leichten Vorteil), aber wennn == null
if/else ist viel schneller. Warum?n == null
die VM erstellen müssen Sie ein neues exception-Objekt und füllen in der stack-trace. Der stack trace-info ist wirklich zu teuer zu erwerben, hier also der try/catch-version ist viel teurer.if
Sie denken, Sie entkommen zu Billig, wennn != null
. Die Sache ist jedoch, dass die VM eine implizite null-check beim dereferenzieren..., dass ist, es sei denn, der JIT kann bestimmen, dassn
darf nicht null sein, was es in der if/else " - version. Dies bedeutet, dass die if/else-und try/catch-Versionen sollten durchgeführt werden, die etwa die gleiche. Aber...InformationsquelleAutor der Antwort gustafc
Neben der guten Antworten (Ausnahmen bei außergewöhnlichen Fällen) ich sehe, Sie sind im Grunde versucht, zu vermeiden, die null-Prüfungen überall. Java 7 wird eine "null-safe" - operator, der den Wert null zurück, wenn
n?.foo()
heißt er wirft eine NPE. Das ist entlehnt aus der Groovy-Sprache. Es gibt auch eine Tendenz zu vermeiden, mit null insgesamt im code, außer wenn es wirklich nötig haben (dh: der Umgang mit Bibliotheken). Die andere Antwort für weitere Diskussion über dieses.Vermeidung != null-Aussagen
InformationsquelleAutor der Antwort Alkaline
Es ist in der Regel teuer, die Ausnahmen behandeln. Die Die VM-Spec könnte geben Ihnen einen Einblick in, wie viel, aber in dem genannten Fall
if (n != null) n.foo();
ist schneller.Obwohl ich Stimme mit Mitch Weizen in Bezug auf die wirkliche Frage ist die Richtigkeit.
@Mitch Weizen - In seiner Verteidigung dies ist eine ziemlich gekünstelt Beispiel. 🙂
InformationsquelleAutor der Antwort linuxuser27
Den wenn Konstrukt ist schneller. Die Bedingung kann leicht übersetzt werden zu Maschinen-code (Prozessor-Anweisungen).
Die alternative (try-catch -) erfordert die Schaffung einer NullPointerException Objekt.
InformationsquelleAutor der Antwort Andreas_D
Definitiv zweite form ist viel schneller. In der
try-catch
Szenario, es wirft einexception
die nichtnew Exception()
irgendeiner form. Dann diecatch
- block wird aufgerufen, die eine Methode aufrufen und ausführen, was code ist. Sie erhalten die Idee.InformationsquelleAutor der Antwort fastcodejava
Erstens die if.. then .. else ist besser, für die es zahlreiche Gründe hingewiesen, die durch die anderen Poster.
Allerdings ist es nicht necceseraly schneller! Es richtet sich ausschliesslich auf die Ernährung der null-Objekte, die keine null-Objekte. Es dauert wohl ein Hunderte von den tausenden Zeiten, die Ressourcen zum verarbeiten eher die Ausnahme als test für die null, jedoch, wenn ein null-Objekt wird nur einmal für jede million Objekte dann die Ausnahme-option wird etwas schneller. Aber nicht so viel schneller dass es sich lohnt machen Sie Ihr Programm schlechter lesbar und schwerer zu Debuggen.
InformationsquelleAutor der Antwort James Anderson
if-else ist schneller, weil ein try-catch-block wirft eine exception stack trace.
Sie können es nehmen, wie für die If-Else-block ausgeführt wird, eine Anweisung zu tun, die Bewertung, aber die Try-Catch wird ausgeführt, Tausende von Anweisungen zum erhöhen der Ausnahme, wenn es passiert.
InformationsquelleAutor der Antwort FearUs
Dieses Problem erörtert hat, die vor kurzem von Dr. Heinz:
http://javaspecialists.eu/webinars/recordings/if-else-npe-teaser.mov
InformationsquelleAutor der Antwort Radi