Sind Ausnahmen in C ++ wirklich langsam?

98

Ich habe die systematische Fehlerbehandlung in C ++ beobachtet - Andrei Alexandrescu behauptet, dass Ausnahmen in C ++ sehr, sehr langsam sind.

Gilt das noch für C ++ 98?

Avinash
quelle
42
Es macht keinen Sinn zu fragen, ob "C ++ 98-Ausnahmen" schneller / langsamer sind als "C ++ 03-Ausnahmen" oder "C ++ 11-Ausnahmen". Ihre Leistung hängt davon ab, wie der Compiler sie in Ihren Programmen implementiert, und der C ++ - Standard sagt nichts darüber aus, wie sie implementiert werden sollen. Die einzige Voraussetzung ist, dass ihr Verhalten dem Standard (der "Als-ob" -Regel) entspricht.
In silico
Verwandte (aber nicht wirklich doppelte) Frage: stackoverflow.com/questions/691168/…
Philipp
2
Ja, es ist sehr langsam, aber sie sollten nicht für einen normalen Betrieb geworfen oder als Zweig verwendet werden
BЈовић
Ich habe eine ähnliche Frage gefunden .
PaperBirdMaster
Um zu klären, was BЈовић gesagt hat, ist die Verwendung von Ausnahmen kein Grund zur Angst. Wenn eine Ausnahme ausgelöst wird, treten (möglicherweise) zeitaufwändige Vorgänge auf. Ich bin auch neugierig, warum Sie speziell für C ++ 89 wissen möchten ... dass die neueste Version C ++ 11 ist und die Zeit, die für die Ausführung von Ausnahmen benötigt wird, durch die Implementierung definiert ist, daher ist mein "potenziell" zeitaufwändig .
Thecoshman

Antworten:

162

Das heute für Ausnahmen verwendete Hauptmodell (Itanium ABI, VC ++ 64 Bit) sind die Zero-Cost-Modellausnahmen.

Die Idee ist, dass der Compiler keine Zeit verliert, indem er einen Guard einrichtet und explizit auf das Vorhandensein von Ausnahmen überall prüft, sondern eine Beistelltabelle generiert, die jeden Punkt, der eine Ausnahme (Programmzähler) auslösen kann, einer Liste von Handlern zuordnet. Wenn eine Ausnahme ausgelöst wird, wird diese Liste konsultiert, um den richtigen Handler (falls vorhanden) auszuwählen, und der Stapel wird abgewickelt.

Im Vergleich zur typischen if (error)Strategie:

  • Das Zero-Cost-Modell ist, wie der Name schon sagt, kostenlos, wenn keine Ausnahmen auftreten
  • Es kostet ungefähr 10x / 20x und ifwenn eine Ausnahme auftritt

Die Kosten sind jedoch nicht trivial zu messen:

  • Der Beistelltisch ist im Allgemeinen kalt , und das Abrufen aus dem Speicher dauert daher lange
  • Das Ermitteln des richtigen Handlers umfasst RTTI: Viele RTTI-Deskriptoren zum Abrufen, Streuen im Speicher und Ausführen komplexer Operationen (im Grunde ein dynamic_castTest für jeden Handler)

Daher fehlen meistens Cache-Fehler und sind daher im Vergleich zu reinem CPU-Code nicht trivial.

Hinweis: Weitere Informationen finden Sie im TR18015-Bericht, Kapitel 5.4 Ausnahmebehandlung (pdf).

Ja, Ausnahmen sind auf dem außergewöhnlichen Pfad langsam , aber ansonsten schneller als explizite Überprüfungen ( ifStrategie) im Allgemeinen.

Hinweis: Andrei Alexandrescu scheint dies "schneller" in Frage zu stellen. Ich persönlich habe gesehen, dass die Dinge in beide Richtungen schwingen, wobei einige Programme mit Ausnahmen schneller sind und andere mit Zweigen schneller, so dass es unter bestimmten Bedingungen tatsächlich zu einem Verlust der Optimierbarkeit kommt.


Ist das wichtig?

Ich würde behaupten, dass dies nicht der Fall ist. Ein Programm sollte unter Berücksichtigung der Lesbarkeit und nicht der Leistung geschrieben werden (zumindest nicht als erstes Kriterium). Ausnahmen sind zu verwenden, wenn man erwartet, dass der Anrufer den Fehler nicht sofort behandeln kann oder will und ihn den Stapel weitergibt. Bonus: In C ++ 11 können Ausnahmen mithilfe der Standardbibliothek zwischen Threads aufgeteilt werden.

Dies ist zwar subtil, ich behaupte, das map::findsollte nicht geworfen werden, aber ich kann map::findeinen zurückgeben, checked_ptrder wirft, wenn ein Versuch der Dereferenzierung fehlschlägt, weil er null ist: Im letzteren Fall, wie im Fall der von Alexandrescu eingeführten Klasse, wählt der Anrufer zwischen expliziter Prüfung und Verlassen auf Ausnahmen. Die Befähigung des Anrufers, ohne ihm mehr Verantwortung zu übertragen, ist normalerweise ein Zeichen für gutes Design.

Matthieu M.
quelle
3
+1 Ich möchte nur vier Dinge hinzufügen: (0) über die in C ++ 11 hinzugefügte Unterstützung für das erneute Werfen; (1) ein Verweis auf den Bericht des Ausschusses über die Effizienz von c ++; (2) einige Bemerkungen zur Korrektheit (die sogar die Lesbarkeit übertrumpfen); und (3) über die Leistung, Anmerkungen zur Messung anhand des Falls, dass keine Ausnahmen verwendet werden (alles ist relativ)
Prost und hth. - Alf
2
@ Cheersandhth.-Alf: (0), (1) und (3) fertig: danke. In Bezug auf die Korrektheit (2) bin ich mir nicht sicher, ob Ausnahmen zu korrekterem Code führen als bei anderen Strategien zur Fehlerbehandlung (es ist so leicht, die vielen unsichtbaren Pfade für Ausführungsausnahmen zu vergessen).
Matthieu M.
2
Die Beschreibung mag lokal korrekt sein, aber es kann erwähnenswert sein, dass das Vorhandensein von Ausnahmen globale Auswirkungen auf Annahmen und Optimierungen hat, die der Compiler vornehmen kann. Diese Implikationen haben das Problem, dass sie "keine trivialen Gegenbeispiele" haben, da der Compiler immer ein kleines Programm durchschauen kann. Eine Profilerstellung auf einer realistischen, großen Codebasis mit und ohne Ausnahmen kann eine gute Idee sein.
Kerrek SB
4
> Das Zero-Cost-Modell ist, wie der Name schon sagt, kostenlos, wenn keine Ausnahme auftritt. Dies gilt nicht bis ins kleinste Detail. Das Generieren von mehr Code wirkt sich immer auf die Leistung aus, auch wenn es klein und subtil ist. Es kann etwas länger dauern, bis das Betriebssystem die ausführbare Datei lädt, oder Sie erhalten mehr I-Cache-Fehler. Und was ist mit dem Abwickeln von Stack-Code? Und was ist mit den Experimenten, die Sie durchführen können, um die Auswirkungen zu messen, anstatt zu versuchen, sie mit rationalem Denken zu verstehen?
Jheriko
2
@jheriko: Ich glaube, ich habe die meisten Ihrer Fragen bereits beantwortet. Die Zeit zum Laden sollte nicht beeinflusst werden (kalter Code sollte nicht geladen werden), der i-Cache sollte nicht beeinflusst werden (kalter Code sollte nicht in den i-Cache gelangen), ... um die eine fehlende Frage zu beantworten: "How to Measure" => Wenn Sie eine Ausnahme ersetzen, die durch einen Aufruf von ausgelöst abortwird, können Sie den Footprint der Binärgröße messen und überprüfen, ob sich die Ladezeit / der i-Cache ähnlich verhalten. Natürlich besser nicht treffen abort...
Matthieu M.
60

Als die Frage gestellt wurde, war ich mit einem wartenden Taxi auf dem Weg zum Arzt, also hatte ich nur Zeit für einen kurzen Kommentar. Aber nachdem ich jetzt kommentiert und hoch- und runtergestimmt habe, füge ich besser meine eigene Antwort hinzu. Auch wenn Matthieus Antwort schon ziemlich gut ist.


Sind Ausnahmen in C ++ im Vergleich zu anderen Sprachen besonders langsam?

Bezüglich des Anspruchs

"Ich habe die systematische Fehlerbehandlung in C ++ beobachtet - Andrei Alexandrescu behauptet, dass Ausnahmen in C ++ sehr, sehr langsam sind."

Wenn Andrei das buchstäblich behauptet, dann ist er ausnahmsweise einmal sehr irreführend, wenn nicht geradezu falsch. Denn eine ausgelöste / ausgelöste Ausnahme ist im Vergleich zu anderen Grundoperationen in der Sprache unabhängig von der Programmiersprache immer langsam . Nicht nur in C ++ oder mehr in C ++ als in anderen Sprachen, wie die angebliche Behauptung zeigt.

Im Allgemeinen, meistens unabhängig von der Sprache, sind die beiden grundlegenden Sprachmerkmale, die um Größenordnungen langsamer sind als die anderen, weil sie sich in Aufrufe von Routinen übersetzen lassen, die komplexe Datenstrukturen verarbeiten

  • Ausnahme werfen, und

  • dynamische Speicherzuordnung.

Glücklicherweise kann man in C ++ oft beides in zeitkritischem Code vermeiden.

Leider gibt es kein kostenloses Mittagessen , auch wenn die Standardeffizienz von C ++ ziemlich nahe kommt. :-) Für die Effizienz, die durch das Vermeiden von Ausnahmefällen und die dynamische Speicherzuweisung erzielt wird, wird im Allgemeinen eine Codierung auf einer niedrigeren Abstraktionsebene erreicht, wobei C ++ nur als „besseres C“ verwendet wird. Und eine geringere Abstraktion bedeutet eine größere „Komplexität“.

Höhere Komplexität bedeutet mehr Zeit für die Wartung und wenig oder gar keinen Nutzen aus der Wiederverwendung von Code. Dies sind reale Geldkosten, selbst wenn sie schwer abzuschätzen oder zu messen sind. Das heißt, mit C ++ kann man, falls gewünscht, eine gewisse Programmiereffizienz gegen Ausführungseffizienz eintauschen. Ob dies zu tun ist, ist größtenteils eine Entscheidung für Technik und Bauchgefühl, da in der Praxis nur der Gewinn und nicht die Kosten leicht geschätzt und gemessen werden können.


Gibt es objektive Messgrößen für die Leistung beim Auslösen von C ++ - Ausnahmen?

Ja, das internationale C ++ - Standardisierungskomitee hat einen technischen Bericht zur C ++ - Leistung, TR18015, veröffentlicht .


Was bedeutet es , dass Ausnahmen „langsam“ sind?

Hauptsächlich bedeutet dies, dass a aufgrund der Suche nach einem Handler throweine sehr lange Zeit ™ im Vergleich zu beispielsweise einer intAufgabe dauern kann .

Wie in TR18015 in Abschnitt 5.4 „Ausnahmen“ erläutert, gibt es zwei Hauptstrategien für die Implementierung von Ausnahmebehandlungen:

  • der Ansatz, bei dem jeder tryBlock dynamisch das Ausfangen von Ausnahmen einrichtet, so dass eine Suche in der dynamischen Kette von Handlern durchgeführt wird, wenn eine Ausnahme ausgelöst wird, und

  • Der Ansatz, bei dem der Compiler statische Nachschlagetabellen generiert, mit denen der Handler für eine ausgelöste Ausnahme ermittelt wird.

Der erste sehr flexible und allgemeine Ansatz wird in 32-Bit-Windows fast erzwungen, während in 64-Bit-Land und in * nix-Land häufig der zweite weitaus effizientere Ansatz verwendet wird.

Wie in diesem Bericht erläutert, gibt es für jeden Ansatz drei Hauptbereiche, in denen sich die Ausnahmebehandlung auf die Effizienz auswirkt:

  • try-Blöcke,

  • reguläre Funktionen (Optimierungsmöglichkeiten) und

  • throw-Ausdrücke.

Vor allem beim dynamischen Handler-Ansatz (32-Bit-Windows) wirkt sich die Ausnahmebehandlung auf tryBlöcke aus, meist unabhängig von der Sprache (da dies durch das strukturierte Ausnahmebehandlungsschema von Windows erzwungen wird ), während der statische Tabellenansatz ungefähr keine Kosten für try- verursacht. Blöcke. Dies zu diskutieren würde viel mehr Platz und Forschung erfordern, als für eine SO-Antwort praktisch ist. Weitere Informationen finden Sie im Bericht.

Leider ist der Bericht aus dem Jahr 2006 bereits Ende 2012 etwas veraltet, und meines Wissens gibt es nichts Vergleichbares, das neuer ist.

Eine weitere wichtige Perspektive ist, dass sich die Auswirkungen der Verwendung von Ausnahmen auf die Leistung stark von der isolierten Effizienz der unterstützenden Sprachfunktionen unterscheiden, da, wie der Bericht feststellt,

"Wenn es um die Behandlung von Ausnahmen geht, muss dies im Gegensatz zu alternativen Methoden zum Umgang mit Fehlern stehen."

Beispielsweise:

  • Wartungskosten aufgrund unterschiedlicher Programmierstile (Richtigkeit)

  • Redundante ifÜberprüfung von Anrufstellenfehlern im Vergleich zu zentralisiertentry

  • Caching-Probleme (z. B. kann kürzerer Code in den Cache passen)

Der Bericht enthält eine andere Liste von Aspekten, die berücksichtigt werden müssen. Der einzige praktische Weg, um harte Fakten über die Ausführungseffizienz zu erhalten, besteht jedoch wahrscheinlich darin, dasselbe Programm mit Ausnahme und nicht mit Ausnahmen innerhalb einer festgelegten Entwicklungszeit und mit Entwicklern zu implementieren mit jedem Weg vertraut und dann MESSEN .


Was ist ein guter Weg, um den Overhead von Ausnahmen zu vermeiden?

Korrektheit übertrifft fast immer die Effizienz.

Ohne Ausnahmen kann Folgendes leicht passieren:

  1. Ein Code P soll eine Ressource erhalten oder Informationen berechnen.

  2. Der aufrufende Code C sollte auf Erfolg / Misserfolg geprüft haben, tut dies aber nicht.

  3. Eine nicht vorhandene Ressource oder ungültige Informationen werden im Code nach C verwendet, was zu allgemeinem Chaos führt.

Das Hauptproblem ist Punkt (2), wo mit dem üblichen Rückkehrcode- Schema der aufrufende Code C nicht zur Überprüfung gezwungen wird.

Es gibt zwei Hauptansätze, die eine solche Überprüfung erzwingen:

  • Wobei P direkt eine Ausnahme auslöst, wenn dies fehlschlägt.

  • Wobei P ein Objekt zurückgibt, das C überprüfen muss, bevor es seinen Hauptwert verwendet (andernfalls eine Ausnahme oder Beendigung).

Der zweite Ansatz war AFAIK, der zuerst von Barton und Nackman in ihrem Buch * Scientific and Engineering C ++: Eine Einführung mit fortgeschrittenen Techniken und Beispielen beschrieben wurde , in dem sie eine Klasse einführten, die Fallowein „mögliches“ Funktionsergebnis forderte . Eine ähnliche Klasse namens optionalwird jetzt von der Boost-Bibliothek angeboten. Und Sie können eine OptionalKlasse einfach selbst implementieren , indem Sie einen std::vectorWerteträger für den Fall eines Nicht-POD-Ergebnisses verwenden.

Beim ersten Ansatz hat der aufrufende Code C keine andere Wahl, als Ausnahmebehandlungstechniken zu verwenden. Beim zweiten Ansatz kann der aufrufende Code C jedoch selbst entscheiden, ob eine ifbasierte Prüfung oder eine allgemeine Ausnahmebehandlung durchgeführt werden soll. Somit unterstützt der zweite Ansatz das Abwägen des Programmierers gegenüber der Effizienz der Ausführungszeit.


Welche Auswirkungen haben die verschiedenen C ++ - Standards auf die Ausnahmeleistung?

"Ich möchte wissen, ob dies für C ++ 98 immer noch gilt."

C ++ 98 war der erste C ++ - Standard. Für Ausnahmen wurde eine Standardhierarchie von Ausnahmeklassen eingeführt (leider eher unvollkommen). Die Hauptauswirkung auf die Leistung war die Möglichkeit von Ausnahmespezifikationen (in C ++ 11 entfernt), die jedoch vom Windows C ++ - Hauptcompiler Visual C ++ nie vollständig implementiert wurden: Visual C ++ akzeptiert die Syntax der C ++ 98-Ausnahmespezifikation, ignoriert diese jedoch Ausnahmespezifikationen.

C ++ 03 war nur eine technische Berichtigung von C ++ 98. Das einzig wirklich Neue in C ++ 03 war die Wertinitialisierung . Was nichts mit Ausnahmen zu tun hat.

Mit dem C ++ 11-Standard wurden allgemeine Ausnahmespezifikationen entfernt und durch das noexceptSchlüsselwort ersetzt.

Der C ++ 11-Standard bietet außerdem Unterstützung für das Speichern und erneute Auslösen von Ausnahmen, was sich hervorragend für die Weitergabe von C ++ - Ausnahmen über C-Sprachrückrufe eignet. Diese Unterstützung schränkt effektiv ein, wie die aktuelle Ausnahme gespeichert werden kann. Soweit ich weiß, wirkt sich dies jedoch nicht auf die Leistung aus, außer in dem Maße, in dem in neueren Codes die Ausnahmebehandlung auf beiden Seiten eines Rückrufs in C-Sprache einfacher verwendet werden kann.

Prost und hth. - Alf
quelle
6
"Ausnahmen sind im Vergleich zu anderen grundlegenden Operationen in der Sprache immer langsam, unabhängig von der Programmiersprache" ... außer in Sprachen, die die Verwendung von Ausnahmen in die normale Flusskontrolle kompilieren sollen.
Ben Voigt
4
"Das Auslösen einer Ausnahme beinhaltet sowohl das Zuweisen als auch das Abwickeln des Stapels". Das trifft natürlich auch im Allgemeinen nicht zu, und auch hier ist OCaml ein Gegenbeispiel. In Garbage-Collected-Sprachen muss der Stack nicht abgewickelt werden, da es keine Destruktoren gibt, sodass Sie nur longjmpzum Handler gehen.
JD
2
@ JonHarrop: Vermutlich wissen Sie nicht, dass Pyhon eine finally-Klausel für die Ausnahmebehandlung hat. Dies bedeutet, dass eine Python-Implementierung entweder über das Abwickeln des Stapels verfügt oder nicht Python ist. Sie scheinen die Themen, über die Sie (Fantasie-) Behauptungen aufstellen, völlig zu ignorieren. Es tut uns leid.
Prost und hth. - Alf
2
@ Cheersandhth.-Alf: "Pyhon hat eine finally-Klausel für die Ausnahmebehandlung. Dies bedeutet, dass eine Python-Implementierung entweder das Abwickeln des Stapels hat oder nicht Python ist." Das try..finallyKonstrukt kann ohne Abwickeln des Stapels implementiert werden. F #, C # und Java werden alle try..finallyohne Stack-Abwicklung implementiert . Sie nur longjmpzum Handler (wie ich bereits erklärt habe).
JD
4
@JonHarrop: Sie klingen wie ein Dilemma aufwirft. aber es hat keine Relevanz, die ich für irgendetwas sehen kann, das bisher diskutiert wurde, und bis jetzt haben Sie eine lange Sequenz von negativ klingendem Unsinn gepostet . Ich müsste dir vertrauen, um einer vagen Formulierung zuzustimmen oder nicht, denn als Antagonist wählst du, was du enthüllen willst, dass es "bedeutet", und ich vertraue dir nach all dem bedeutungslosen Unsinn, Abstimmen usw. sicherlich nicht .
Prost und hth. - Alf
13

Sie können niemals einen Anspruch auf Leistung erheben, es sei denn, Sie konvertieren den Code in die Assembly oder vergleichen ihn.

Folgendes sehen Sie: (Schnellbank)

Der Fehlercode ist nicht abhängig vom Prozentsatz des Auftretens. Ausnahmen haben etwas Aufwand, solange sie nie geworfen werden. Sobald Sie sie werfen, beginnt das Elend. In diesem Beispiel wird es für 0%, 1%, 10%, 50% und 90% der Fälle ausgelöst. Wenn die Ausnahmen in 90% der Fälle ausgelöst werden, ist der Code achtmal langsamer als in dem Fall, in dem die Ausnahmen in 10% der Fälle ausgelöst werden. Wie Sie sehen, sind die Ausnahmen sehr langsam. Verwenden Sie sie nicht, wenn sie häufig geworfen werden. Wenn für Ihre Anwendung keine Echtzeitanforderungen gelten, können Sie diese gerne auslösen, wenn sie sehr selten auftreten.

Sie sehen viele widersprüchliche Meinungen über sie. Aber schließlich sind Ausnahmen langsam? Ich urteile nicht. Beobachten Sie einfach den Benchmark.

Leistungsbenchmark für C ++ - Ausnahmen

Arash
quelle
12

Das hängt vom Compiler ab.

GCC zum Beispiel war dafür bekannt, dass es beim Umgang mit Ausnahmen eine sehr schlechte Leistung zeigte, die sich jedoch in den letzten Jahren erheblich verbessert hat.

Beachten Sie jedoch, dass die Behandlung von Ausnahmen - wie der Name schon sagt - eher die Ausnahme als die Regel in Ihrem Software-Design sein sollte. Wenn Sie eine Anwendung haben, die so viele Ausnahmen pro Sekunde auslöst, dass sie die Leistung beeinträchtigt und dies immer noch als normaler Betrieb angesehen wird, sollten Sie lieber darüber nachdenken, die Dinge anders zu machen.

Ausnahmen sind eine großartige Möglichkeit, den Code lesbarer zu machen, indem all der umständliche Fehlerbehandlungscode aus dem Weg geräumt wird. Sobald sie jedoch Teil des normalen Programmablaufs werden, ist es sehr schwierig, ihnen zu folgen. Denken Sie daran, dass a throwso ziemlich eine goto catchVerkleidung ist.

Philipp
quelle
-1 bezüglich der Frage, wie sie jetzt steht, "gilt dies immer noch für C ++ 98", die sicherlich nicht vom Compiler abhängt. Auch diese Antwort throw new Exceptionist ein Java-Ismus. man sollte in der Regel niemals Zeiger werfen.
Prost und hth. - Alf
1
schreibt der 98-Standard genau vor, wie Ausnahmen implementiert werden sollen?
Thecoshman
6
C ++ 98 ist ein ISO-Standard, kein Compiler. Es gibt viele Compiler, die es implementieren.
Philipp
3
@thecoshman: Nein. Der C ++ - Standard sagt nichts darüber aus, wie etwas implementiert werden soll (mit der möglichen Ausnahme des Teils "Implementierungsgrenzen" des Standards).
In silico
2
@Insilico dann kann ich nur die logische Schlussfolgerung ziehen, dass (schockierend) die Implementierung definiert ist (gelesen, compilerspezifisch), wie Ausnahmen ausgeführt werden.
Thecoshman
4

Ja, aber das spielt keine Rolle. Warum?
Lesen Sie dies:
https://blogs.msdn.com/b/ericlippert/archive/2008/09/10/vexing-exceptions.aspx

Grundsätzlich heißt das, dass die Verwendung von Ausnahmen wie der von Alexandrescu beschriebenen (50-fache Verlangsamung, weil sie catchals verwendet werden else) einfach falsch ist. Davon abgesehen würde ich für Leute, die es gerne so machen, C ++ 22 wünschen :) Folgendes hinzufügen:
(Beachten Sie, dass dies die Kernsprache sein muss, da es sich im Grunde um einen Compiler handelt, der Code aus einer vorhandenen generiert.)

result = attempt<lexical_cast<int>>("12345");  //lexical_cast is boost function, 'attempt'
//... is the language construct that pretty much generates function from lexical_cast, generated function is the same as the original one except that fact that throws are replaced by return(and exception type that was in place of the return is placed in a result, but NO exception is thrown)...     
//... By default std::exception is replaced, ofc precise configuration is possible
if (result)
{
     int x = result.get(); // or result.result;
}
else 
{
     // even possible to see what is the exception that would have happened in original function
     switch (result.exception_type())
     //...

}

PS bemerkt auch, dass selbst wenn die Ausnahmen so langsam sind ... es kein Problem ist, wenn Sie während der Ausführung nicht viel Zeit in diesem Teil des Codes verbringen ... Zum Beispiel, wenn die Float-Division langsam ist und Sie es 4x machen schneller, das spielt keine Rolle, wenn Sie 0,3% Ihrer Zeit mit FP-Division verbringen ...

NoSenseEtAl
quelle
0

Wie in silico sagte, ist seine Implementierung abhängig, aber im Allgemeinen werden Ausnahmen für jede Implementierung als langsam angesehen und sollten nicht in leistungsintensivem Code verwendet werden.

EDIT: Ich sage nicht, dass Sie sie überhaupt nicht verwenden, aber für leistungsintensiven Code ist es am besten, sie zu vermeiden.

Chris McCabe
quelle
9
Dies ist bestenfalls eine sehr vereinfachte Sichtweise auf die Ausnahmeleistung. Beispielsweise verwendet GCC eine "Null-Kosten" -Implementierung, bei der Sie keinen Leistungseinbruch erleiden, wenn keine Ausnahmen ausgelöst werden. Und Ausnahmen sind für außergewöhnliche (dh seltene) Umstände gedacht. Selbst wenn sie durch eine Metrik langsam sind, ist dies immer noch kein Grund genug, sie nicht zu verwenden.
In silico
@insilico Wenn Sie sich ansehen, warum ich gesagt habe, habe ich nicht gesagt, keine Ausnahmen Punkt zu verwenden. Ich habe leistungsintensiven Code angegeben. Dies ist eine genaue Einschätzung. Ich arbeite hauptsächlich mit gpgpus und ich werde erschossen, wenn ich Ausnahmen verwende.
Chris McCabe