verlangsamen Auf welche Weise Ausnahmen Code Sie C ++, wenn es keine Ausnahmen geworfen?

StackOverflow https://stackoverflow.com/questions/1897940

  •  19-09-2019
  •  | 
  •  

Frage

Ich habe gelesen, dass es einige Kopf ++ Ausnahmen für die Ausnahmebehandlung zur Verwendung von C ist im Gegensatz zu, sagen wir, Rückgabewerte überprüfen. Ich spreche nur über Overhead, die anfallen, wenn keine Ausnahme ausgelöst. Ich gehe davon aus, dass Sie den Code implementieren müssen, die den Rückgabewert tatsächlich überprüft und machen die entsprechende Sache, was auch immer die äquivalent zu dem, was der catch-Block hätte getan wäre. Und es ist auch nicht fair Code zu vergleichen, die Ausnahme-Objekte mit 45 Zustandsvariablen innerhalb von Code führt, die für jeden Fehler eine negative ganze Zahl zurückgibt.

Ich versuche nicht, einen Fall für oder gegen C ++ Ausnahmen ausschließlich auf Basis aufzubauen, auf die man schneller ausführen könnte. Ich hörte, wie jemand, den Fall vor kurzem, dass Code machen Ausnahmen verwenden sollte nur so schnell laufen wie auf Rückgabecodes Code basiert, wenn Sie berücksichtigen alle zusätzlichen Buchhaltung Code, der die Rückgabewerte werden benötigt würden zu prüfen und die Fehler zu behandeln. Was bin ich?

War es hilfreich?

Lösung

Es gibt ein Kosten mit Ausnahmebehandlung zugeordnet ist, auf einige Plattformen und mit einig Compiler.

Das heißt, Visual Studio, wenn ein 32-Bit-Ziel baut, wird eine Prozedur in jeder Funktion registrieren, die lokalen Variablen mit nicht-trivial destructor hat. Im Grunde ist es setzt einen try/finally Handler auf.

Die andere Technik, eingesetzt von gcc und Visual Studio Targeting 64-Bit, nur Overhead entstehen, wenn eine Ausnahme ist geworfen (die Technik den Call-Stack und Nachschlagen in einer Tabelle beinhaltet durchlaufen). In Fällen, in denen Ausnahmen selten geworfen werden, kann dies tatsächlich zu einer effizienteren Code führen, da Fehlercodes nicht verarbeitet werden muß.

Andere Tipps

Nur try / catch und versuchen, / außer Block ein paar Anweisungen nehmen einzurichten. Der Overhead sollte in jedem Fall mit Ausnahme der tighest Schleifen im Allgemeinen vernachlässigbar. Aber Sie würden normalerweise nicht verwenden try / catch / außer in einer inneren Schleife trotzdem.

Ich würde raten, nicht zu kümmern, und einen Profiler zu verwenden, anstatt Ihren Code zu optimieren, wo nötig.

Es ist völlig abhängig von der Implementierung, aber in letzter Zeit viele Implementierungen haben sehr wenig oder keine Performance-Overhead, wenn Ausnahmen sind nicht geworfen. In der Tat haben Sie Recht. Korrekt Rückgabecodes von allen Funktionen im Code überprüft, die dann nichts zu tun für Code mit Ausnahmen langsamer keine Ausnahmen verwendet werden.

Natürlich müßten Sie die Leistung für Ihre speziellen Anforderungen messen sicher sein.

Es ist einige Overhead mit Ausnahmen (wie die anderen Antworten darauf hingewiesen).

Aber Sie haben nicht viel von einer Wahl heute. Versuchen Sie deaktivieren Ausnahmen in Ihrem Projekt, und stellen Sie sicher, dass alle abhängigen Code und Bibliotheken können kompilieren und ausführen, ohne.

Sie arbeiten sie mit Ausnahmen deaktiviert?

Nehmen wir an, sie tun! Dann Benchmark einige Fälle, aber beachten Sie, dass Sie ein „deaktivieren Ausnahmen“ zu setzen haben Schalter kompilieren. Ohne diesen Schalter haben Sie noch die Overhead - auch wenn der Code nie Ausnahmen auslöst

.

Nur Overhead ~ 6 Anweisungen, die 2 SEH zu Beginn der Funktion hinzufügen, und lassen Sie sie am Ende. Egal, wie viele versuchen / fängt man in einem Thread hat, ist es immer das gleiche.

Auch was ist das über lokale Variablen? Ich höre die Leute immer über sie beschweren, wenn versuchen, mit / catch. Ich verstehe es nicht, denn der deconstructors schließlich sowieso nennen würde. Auch sollte man nicht eine Ausnahme nach oben mehr als 1-3 Anrufe werden zu lassen.

Ich nahm Chip Uni-Test-Code und erweitert es ein wenig. Ich spaltete den Code in zwei Quelldateien (eines mit Ausnahmen, eine ohne). Ich habe jedem Benchmark-Lauf 1000-mal, und ich clock_gettime() mit CLOCK_REALTIME die Start- und Endzeiten jeder Iteration aufzuzeichnen. Dann berechnet ich den Mittelwert und die Varianz der Daten. Ich lief diesen Test mit 64-Bit-Versionen von g ++ 5.2.0 und Klirren ++ 3.7.0 auf einem Intel Core i7-Box mit 16 GB RAM, die ArchLinux mit Kernel 4.2.5-1-ARCH läuft. Sie können den erweiterten Code finden und die vollständigen Ergebnisse hier .

g ++

Keine Ausnahmen
  • Durchschnitt: 30022994 ns
  • Standardabweichung: 1.25327e + 06 ns
Ausnahmen
  • Durchschnitt: 30025642 ns
  • Standardabweichung: 1.83422e + 06 ns

Klirren ++

Keine Ausnahmen
  • Durchschnitt: 20954657 ns
  • Standardabweichung: 426.662 ns
Ausnahmen
  • Durchschnitt: 23916638 ns
  • Standardabweichung: 1.72583e + 06 ns

C ++ Ausnahmen entstehen nur eine nicht-triviale Leistungseinbuße mit Klirren ++ und sogar diese Strafe ist nur ~ 14%.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top