2016-09-09 1 views
2

Ich möchte eine Methode erstellen, die mir sagen kann, ob eine Ausnahme erneut versucht werden kann oder nicht. Ausnahmen sind von 3rd-Party-Bibliothek. Also ich habe so etwas wie dies:Leistungseinfluss von langen Fangliste C++

bool isRetryable (std::exception_ptr ex) { 
    try { 
     if(ex) { 
      std::rethrow_exception (ex); 
     } 
     return true; 
    } catch (const ExceptionA& ex) { 
     return true; 
    } catch (const ExceptionB& ex) { 
     return true; 
    } catch (const ExceptionC& ex) { 
     return true; 
    } catch (const ExceptionD& ex) { 
     return false; 
    } catch (const ExceptionE& ex) { 
     return false; 
    } catch (const ExceptionF& ex) { 
     return false; 
    } 
} 

Die Liste der Ausnahmen als 100 so lange gehen kann, so meine Frage ist - was die Auswirkungen einer langen Liste von Ausnahme und gibt es eine andere Möglichkeit, das gleiche zu erreichen Tor ?

+0

Ich meine, Sie können versuchen, sich selbst zu messen. Wenn die Ausnahmen eine gemeinsame Basis haben, können Sie dynamic_casts ausprobieren: Wenn sie jedoch schneller sind, müssen Sie messen. – Hayt

Antwort

3

Es hängt von der C++ - Laufzeitbibliothek ab, aber im Allgemeinen führt eine lange Liste von catch-Blöcken zu einer O (n) -Leistung, da die Implementierung einen linearen Scan durchführt und den geworfenen Ausnahmetyp mit jedem der Typen vergleicht Liste der Fangblöcke der Reihe nach; dies ist z.B. wie libstdC++ (die Standard-C++ - Laufzeit unter Linux) funktioniert.

Ich weiß nicht, ob andere Laufzeitbibliotheken dies optimieren, aber ich würde vermuten, dass dies nicht der Fall wäre, da eine lange Liste von Ausnahmeblöcken normalerweise als "Code-Geruch" betrachtet wird und auch die Implementierung erforderlich ist um sicherzustellen, dass der erste übereinstimmende catch-Block die Ausnahme erhält, was einen linearen Scan zur natürlichen Implementierung macht.

Wenn jedoch alle Ihre Ausnahmen von einer polymorphen Base ableiten (zB std::exception) gibt es eine viel elegantere Lösung: Sie können die typeid der Ausnahme nehmen, bauen eine std::type_index und schauen sie in einem Behälter nach oben:

struct ExceptionA : std::exception {}; 
// etc. 

static std::unordered_set<std::type_index> const retryables{ 
    typeid(ExceptionA), 
    typeid(ExceptionB), 
    typeid(ExceptionC) 
}; 

bool isRetryable (std::exception_ptr ex) { 
    try { 
     if(ex) { 
      std::rethrow_exception (ex); 
     } 
     return true; 
    } catch (const std::exception& ex) { 
     return retryables.count(typeid(ex)); 
    } 
} 

Example.

+2

nette Antwort, aber vielleicht noch die Idee, 100 Ausnahmen zu haben und sie alle an einem einzigen Ort zu fangen, deutet wahrscheinlich auf Design-Probleme – stijn

Verwandte Themen