Kann ich die STL verwenden, wenn ich mir die langsame Leistung nicht leisten kann, wenn Ausnahmen ausgelöst werden?

8

Zum Beispiel schreibe ich eine zeitkritische Multi-Thread-Anwendung, die Audio in Echtzeit verarbeitet und streamt. Unterbrechungen im Audio sind völlig inakzeptabel. Bedeutet das, dass ich die STL wegen der möglichen Verlangsamung nicht verwenden kann, wenn eine Ausnahme ausgelöst wird?

    
Carl 02.10.2008, 20:16
quelle

7 Antworten

7

Es ist nicht klar in den vorherigen Antworten geschrieben, also:

Ausnahmen passieren in C ++

Wenn Sie die STL verwenden oder nicht, wird der RAII-Code nicht entfernt, der die von Ihnen zugewiesenen Ressourcen freigibt.

Zum Beispiel:

%Vor%

Im obigen Code erzeugt der Compiler den Code, um die MyString-Ressourcen freizugeben (dh er wird den MyString-Destruktor aufrufen), egal was in der Zwischenzeit passiert, einschließlich wenn eine Ausnahme von doSomethingElse ausgelöst wird oder wenn Sie eine " return "vor dem Ende des Funktionsumfangs.

Wenn Sie ein Problem damit haben, sollten Sie entweder Ihre Denkweise überarbeiten oder C ausprobieren.

Ausnahmen sollen außergewöhnlich sein

Normalerweise, wenn eine Ausnahme auftritt ( und nur wenn ), hast du einen Leistungseinbruch.

Aber dann sollte die Ausnahme nur gesendet werden, wenn:

  • Sie müssen ein außergewöhnliches Ereignis behandeln (d. h. eine Art Fehler)
  • In sehr außergewöhnlichen Fällen (d. h. eine "massive Rückgabe" von mehreren Funktionsaufrufen im Stapel, wie bei einer komplizierten Suche oder beim Abwickeln des Stapels vor einer thread-mäßigen Unterbrechung)

Das Schlüsselwort hier ist "außergewöhnlich", was gut ist, weil wir über "Ausnahme" sprechen (siehe Muster?).

Wenn in Ihrem Fall eine Ausnahme ausgelöst wird, sind die Chancen gut, dass etwas so schlimm passiert ist, dass Ihr Programm trotzdem ohne Ausnahme abgestürzt wäre.

In diesem Fall handelt es sich bei Ihrem Problem nicht um den Leistungseinbruch. Es handelt sich um einen fehlerfreien Umgang mit dem Fehler, oder im schlimmsten Fall eine ordentliche Beendigung Ihres Programms (einschließlich einer "Sorry" -Nachricht, um nicht gespeicherte Daten zur späteren Wiederherstellung in eine temporäre Datei zu speichern, usw.).

Dies bedeutet (außer in Ausnahmefällen), Ausnahmen nicht als "return data" zu verwenden. Ausnahmen auslösen, wenn etwas sehr Schlechtes passiert. Fange eine Ausnahme nur, wenn du weißt, was damit zu tun ist. Vermeiden Sie es, versuchen / fangen (es sei denn, Sie wissen, wie die Ausnahme behandelt wird).

Was ist mit der STL?

Jetzt wissen wir das:

  • Sie möchten immer noch C ++ verwenden
  • Ihr Ziel ist nicht, tausend Ausnahmen jede Sekunde nur für den Spaß davon zu werfen

Wir sollten STL diskutieren:

STL wird (wenn möglich) normalerweise überprüfen, ob Sie etwas falsch machen. Und wenn Sie das tun, wird eine Ausnahme ausgelöst. In C ++ bezahlen Sie normalerweise nicht für etwas, das Sie nicht verwenden werden.

Ein Beispiel dafür ist der Zugriff auf Vektordaten.

Wenn Sie wissen , dass Sie keine Grenzen überschreiten, sollten Sie den Operator [] verwenden.

Wenn Sie wissen , dass Sie die Grenzen nicht überprüfen, sollten Sie die Methode at () verwenden.

Beispiel A:

%Vor%

Beispiel B:

%Vor%

Das Beispiel A "vertraut" dem Programmierer, und keine Zeit wird bei der Verifizierung verloren gehen (und somit weniger Wahrscheinlichkeit einer Ausnahme, die zu dieser Zeit ausgelöst wird , wenn es trotzdem einen Fehler gibt ... Which normalerweise bedeutet der Fehler / Ausnahme / Absturz in der Regel nach, die nicht hilft, zu debuggen und wird mehr Daten beschädigt werden lassen.)

Im Beispiel B wird der Vektor aufgefordert, zu überprüfen, ob der Index korrekt ist. Andernfalls wird eine Ausnahme ausgelöst.

Die Wahl liegt bei Ihnen.

    
paercebal 15.08.2009, 10:45
quelle
28

Im Allgemeinen ist die einzige Ausnahme, die STL-Container selbst auslösen, ein std :: bad_alloc, wenn ein neuer Fehler auftritt. Die anderen Zeiten sind, wenn Benutzercode (zum Beispiel Konstruktoren, Zuordnungen, Kopierkonstruktoren) wirft. Wenn dein Benutzercode niemals würfelt, musst du dich nur vor einem neuen Wurf schützen, was du wahrscheinlich sowieso getan hättest.

Andere Dinge, die Ausnahmen auslösen können: - at () - Funktionen können std :: out_of_range auslösen, wenn Sie auf sie außerhalb der Grenzen zugreifen. Dies ist sowieso ein ernsthafter Programmfehler.

Zweitens sind Ausnahmen nicht immer langsam. Wenn in Ihrer Audioverarbeitung eine Ausnahme auftritt, ist dies wahrscheinlich auf einen schwerwiegenden Fehler zurückzuführen, den Sie ohnehin behandeln müssen. Der Fehlerbehandlungscode wird wahrscheinlich erheblich teurer sein als der Ausnahmebehandlungscode, um die Ausnahme an die Auffangstelle zu transportieren.

    
Greg Rogers 02.10.2008 20:20
quelle
8

Wenn ein STL-Container auslöst, haben Sie wahrscheinlich ein viel größeres Problem als die Verlangsamung:)

    
Nemanja Trifunovic 02.10.2008 20:21
quelle
3

Haben Sie keine Angst vor Ausnahmen in Bezug auf die Leistung.

In den alten Tagen von C ++ konnte ein Build mit aktivierten Exceptions bei manchen Compilern sehr viel langsamer sein.

Heutzutage ist es wirklich egal, ob Ihr Build mit oder ohne Ausnahme funktioniert.

Im Allgemeinen löst STL keine Ausnahmen aus, es sei denn, Sie haben nicht genügend Arbeitsspeicher, so dass dies auch für Ihren Anwendungstyp kein Problem darstellen sollte.

(Verwenden Sie jetzt keine Sprache mit GC .....)

    
Jeroen Dirks 02.10.2008 20:51
quelle
3

Es ist erwähnenswert, einige Punkte:

  • Ihre Anwendung ist multi-threaded. Wenn ein Thread (möglicherweise ein GUI) durch eine Ausnahme verlangsamt wird, sollte dies die Leistung der Echtzeit-Threads nicht beeinträchtigen.

  • Ausnahmen gelten für außergewöhnliche Umstände. Wenn in Ihrem Echtzeit-Thread eine Ausnahme ausgelöst wird, besteht die Gefahr, dass Sie die Wiedergabe von Audio nicht fortsetzen können. Wenn Sie aus irgendeinem Grund feststellen, dass Sie fortwährend Ausnahmen in diesen Threads verarbeiten, müssen Sie das Design so umgestalten, dass die Ausnahmen von vornherein vermieden werden.

Ich würde Ihnen empfehlen, die STL mit ihren Ausnahmen zu akzeptieren (es sei denn, die STL selbst erweist sich als zu langsam - aber denken Sie daran: zuerst messen, zweite optimieren ) und auch die Ausnahmebehandlung für sich übernehmen ' Ausnahmesituationen (Audio-Hardware-Fehler, was auch immer) in Ihrer Anwendung.

    
Roddy 02.10.2008 21:08
quelle
1

Ich habe Mühe, darüber nachzudenken, welche Teile der AWL angeben, dass sie eine Ausnahme auslösen können. Nach meiner Erfahrung wird die meiste Fehlerbehandlung durch Rückgabecodes oder als Voraussetzung für die Verwendung der STL gehandhabt. Ein an die STL übergebenes Objekt könnte definitiv eine Ausnahme auslösen, z. Kopierkonstruktor, aber das wäre unabhängig von der Verwendung von STL ein Problem. Andere haben Funktionen wie std::vector::at() erwähnt, aber Sie können normalerweise eine Überprüfung durchführen oder eine alternative Methode verwenden, um sicherzustellen, dass keine Ausnahme ausgelöst werden kann.

Sicherlich kann eine bestimmte Implementierung der STL "Checks" durchführen, im Allgemeinen für Debug-Builds, auf Ihre Verwendung der STL, ich denke, dass es nur eine Assertion auslösen wird, aber vielleicht werden einige eine Ausnahme auslösen.

Wenn kein Versuch / Fang vorhanden ist, glaube ich, dass kein / minimaler Leistungstreffer eintritt, es sei denn, eine Ausnahme wird von Ihren eigenen Klassen ausgelöst.

In Visual Studio können Sie die Verwendung von C ++ - Ausnahmen vollständig deaktivieren, siehe Project Properties -> C/C++ -> Code Generation -> Enable C++ Exceptions . Ich nehme an, dass dies auf den meisten C ++ - Plattformen verfügbar ist.

    
Henk 02.10.2008 20:29
quelle
0

Sie reden, als ob Ausnahmen unvermeidlich sind. Tun Sie einfach nichts, was eine Ausnahme verursachen könnte - beheben Sie Ihre Fehler, überprüfen Sie Ihre Eingaben.

    
James Curran 02.10.2008 20:58
quelle

Tags und Links