6

Eine ähnliche Frage wurde zu diesem Thema gestellt, aber es wurde nicht genau in den gleichen Begriffen gefragt.Erlang 'Fang' Ausdruck vs Versuch/Fang in Bezug auf Effizienz

Ich versuche, Base64-Binärdateien sicher zu dekodieren, in einem Kontext, in dem es möglich ist, dass die Eingabe keine binäre oder sogar base64-codiert sein wird.

Erlang sagt, lass es abstürzen und damit umgehen - wenn ich dies tun würde, was ist der effizienteste Weg. Effizienz ist in diesem System sehr wichtig.

Ich weiß zu versuchen/fangen, wie es eine vollständige Stack-Trace erstellt - aber ist das Fang-Keyword für diesen Kontext sinnvoll? Und ist das Fang-Keyword schneller/effizienter?

In einer Funktion wie

safe_decode(Binary) -> 
    case catch base64:decode(Binary) of 
     <<Result/binary>> -> {ok, Result}; 
     {'EXIT', _} -> {not_base64, Binary} 
    end. 

Ist das wirklich effizienter als ein Versuch Haken? Wie kann dieses Szenario in einem System am besten gehandhabt werden, in dem Effizienz wichtig ist, d. H. Abstürze, die das Erstellen einer Stapelverfolgung und/oder mehr Verarbeitung als der glückliche Pfad erfordern, müssen so effizient wie möglich gehandhabt werden.

Ich lerne gerade Erlang, also ist die Antwort vielleicht starrt mich ins Gesicht.

Antwort

9

Nein, es ist anders herum: Vermeiden Sie catch, da es immer eine Stack-Trace erstellt. try + catch erstellt nur eine Stack-Trace, wenn Sie es mit erlang:get_stacktrace() fragen.

Siehe Heads-up: The cost of get_stacktrace(), veröffentlicht zu erlang-Fragen von Richard Carlsson am 2013-11-05, für die ganze Geschichte. Lassen Sie mich ein paar Teile zitieren:

(Zusammenfassung: Ausnahmen billig, aber erlang: get_stacktrace() Art teurer, auch, vermeiden 'Fang Ausdr'.)

Es ist natürlich immer noch gültig, get_stacktrace() in vielen Situationen aufzurufen, zB wenn der Prozess aufgibt, aufzugeben oder die Absturzinformationen in ein Protokoll zu schreiben, oder für etwas, was nur selten passiert und die Stack-Trace-Informationen nützlich sind - aber niemals in einer Bibliotheksfunktion, die stark verwendet werden kann in einer Schleife.

Schließlich ist dies auch ein weiterer Grund, alte Vorkommen von 'catch Ausdr' neu zu schreiben in 'versuchen Expr fangen ... end' [...]

+0

Sehr interessant - danke! –

+2

Sie können auch einen makellosen Absturz-Prozess starten, der Ihnen entweder eine Erfolgsmeldung oder eine Todesnachricht (den Monitor) über den Fehler schickt, ohne einen Versuch zu provozieren. * Manchmal * ist dies die ideale Lösung. Manchmal nicht. Wie immer, Benchmark. Wenn Sie eine Menge fehlerhafter Eingabedaten erfassen, sind die Abstürze möglicherweise leichter. Wenn 99% Ihrer Eingabedaten gut sind, ist "try..catch" wahrscheinlich besser. – zxq9

Verwandte Themen