Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Erlang 'catch' expression vs try/catch in terms of efficiency

A similar question was asked about this but it was not exactly asked in the same terms.

I am trying to safely decode base64 binaries, in a context where it's possible the input will not be a binary, or even base64 encoded.

Erlang says let it crash and handle it -- if I were to do this, what is the most efficient way. Efficiency is quite important in this system.

I know to avoid try/catch, as it builds a full stack trace -- however, is the catch keyword reasonable for this context? And is the catch keyword faster/more efficient?

In a function such as

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

Is this truly more efficient than a try catch? How best to handle this scenario in a system where efficiency is important i.e. crashes which involve building a stack trace and/or require more processing than the happy path need to be handled as efficiently as possible.

I'm just learning erlang, so maybe the answer is staring me in the face.

like image 779
Barry Bant Avatar asked Oct 23 '17 09:10

Barry Bant


1 Answers

No, it's the other way around: avoid catch since it always builds a stack trace. try+catch only builds a stack trace if you ask it to with erlang:get_stacktrace().

See Heads-up: The cost of get_stacktrace(), posted to erlang-questions by Richard Carlsson on 2013-11-05, for the full story. Let me cite a few parts:

(Executive summary: exceptions cheap, but erlang:get_stacktrace() kind of expensive; also, avoid 'catch Expr'.)

It's of course still valid to call get_stacktrace() in many situations, e.g. when the process is on its way to give up, or to write the crash information to a log, or for something that only happens rarely and the stack trace information is useful - but never in a library function that might be used heavily in a loop.

Finally, this is also another reason to rewrite old occurrences of 'catch Expr' into 'try Expr catch ... end' [...]

like image 118
legoscia Avatar answered Nov 20 '22 21:11

legoscia