Zusätzlich zu Francescos Antwort scheint es, dass einer der (relativ) teuren Teil des Fangs die Ausnahme ist, die passt:
%Vor%Betrachten Sie die (CPython 2) -Demontage:
%Vor% Beachten Sie, dass der catch-Block die Exception trotzdem lädt und sie mit einer KeyError
vergleicht. In der Tat betrachten wir den except KeyError as ke
-Fall:
Der einzige Unterschied ist ein einzelner STORE_FAST
, um den Ausnahmewert zu speichern (im Falle einer Übereinstimmung). Ähnliches mit mehreren Ausnahmeübereinstimmungen:
Vervielfältigt die Exception und versucht, sie mit jeder aufgelisteten Exception zu vergleichen, bis eine Übereinstimmung gefunden wird, was (wahrscheinlich) als "schlechte Fangleistung" bezeichnet wird.
Ein Python-Programm wird aus Codeblöcken konstruiert. Ein Block ist ein Stück Python-Programmtext, der als eine Einheit ausgeführt wird. In Python wird der Kernblock als struct basisblock dargestellt:
cpython / Python / compile.c
%Vor%Schleifen, try / except und try / finally-Anweisungen haben etwas anderes gehandhabt. Für diese 3 Anweisungen werden Rahmenblock verwendet:
cpython / Python / compile.c
%Vor%Ein Codeblock wird in einem Ausführungsrahmen ausgeführt.
cpython / Include / frameobject.h
%Vor%Ein Rahmen enthält einige administrative Informationen (die zum Debuggen verwendet werden) und bestimmt, wo und wie die Ausführung fortgesetzt wird, nachdem die Ausführung des Codeblocks abgeschlossen ist. Wenn Sie die Anweisung 'as' verwenden (in den Anweisungen 'Importiere etwas als' oder 'Ausnahme Ausnahme als'), benennen Sie einfach den Bindungsvorgang. I.e. Python fügt einfach einen Verweis auf das Objekt in der * f_locals-Symboltabelle des Rahmenobjekts hinzu. Also kein Overhead zur Laufzeit wird nicht sein.
Aber Sie werden bei der Analyse Zeit haben.
cpython / Module / parsermodule.c
%Vor%Aber meiner Meinung nach kann das vernachlässigt werden
Der Catch ist nicht teuer, die Teile, die relativ langsam erscheinen, sind die Erstellung des Stack-Trace selbst und bei Bedarf das anschließende Abwickeln des Stacks.
Jede Stapel-basierte Sprache, von der ich weiß, dass Sie Stack-Traces erfassen können, muss diese Operationen ausführen.
raise
aufgerufen wird, sammeln Sie die Stapelinformationen. Beachten Sie, dass Sie mit Java 1.7 die Stack-Sammlung unterdrücken können und es ist viel schneller, aber Sie verlieren eine Menge nützlicher Informationen. Es gibt keinen vernünftigen Weg für die Sprache zu wissen, wer es fängt, so dass das Ignorieren einer Ausnahme nicht hilft, weil sie ohnehin den größten Teil der Arbeit leisten muss. Der Fang ist im Vergleich zu den beiden obigen Operationen winzig. Hier ist ein Code, der zeigt, dass die Leistung abnimmt, wenn die Stack-Tiefe zunimmt.
%Vor% Die Ausgabe ist, Zeit (Zeiten sind relativ), um Exception()
Jemand, der in Python besser ist als ich, könnte py.test
bekommen, um die Zeiten am Ende zu drucken.
Hinweis: Vor einigen Wochen wurde eine ähnliche Frage zu Java gestellt. Es ist ein sehr informativer Thread unabhängig von der verwendeten Sprache ...
Tags und Links python exception-handling performance