【问题标题】:Erlang 'catch' expression vs try/catch in terms of efficiencyErlang 'catch' 表达式与 try/catch 在效率方面的对比
【发布时间】:2018-04-03 19:01:30
【问题描述】:

有人问过类似的问题,但问的不是完全相同。

我正在尝试安全地解码 base64 二进制文件,但输入可能不是二进制文件,甚至不是 base64 编码的。

Erlang 说让它崩溃并处理它——如果我要这样做,最有效的方法是什么。在这个系统中,效率非常重要。

我知道要避免 try/catch,因为它会构建完整的堆栈跟踪——但是,catch 关键字对于这种情况是否合理? catch 关键字是否更快/更有效?

在诸如

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

这真的比 try catch 更有效吗?如何在效率很重要的系统中最好地处理这种情况,即涉及构建堆栈跟踪和/或需要比快乐路径更多的处理需要尽可能高效地处理的崩溃。

我只是在学习 erlang,所以也许答案就在眼前。

【问题讨论】:

    标签: performance exception erlang runtime-error processing-efficiency


    【解决方案1】:

    不,反之亦然:避免使用catch,因为它总是构建堆栈跟踪。 try+catch 仅在您使用 erlang:get_stacktrace() 要求时构建堆栈跟踪。

    请参阅Heads-up: The cost of get_stacktrace(),Richard Carlsson 于 2013 年 11 月 5 日发布到 erlang-questions 以获取完整故事。让我引用几个部分:

    (执行摘要:异常便宜,但 erlang:get_stacktrace() 种类 昂贵的;另外,避免'catch Expr'。)

    当然在很多情况下调用 get_stacktrace() 还是有效的, 例如当进程正在放弃或写入崩溃时 信息记录到日志中,或者只发生很少的事情,并且 堆栈跟踪信息很有用——但从来没有在库函数中 可能会在循环中大量使用。

    最后,这也是重写旧出现的另一个原因 'catch Expr' 变成 'try Expr catch ... end' [...]

    【讨论】:

    • 您可能还想spawn_monitor 一个无痛可崩溃的过程,它会立即向您发送成功消息或失败的死亡笔记(监视器),而不会鼓励任何try..catch 疯狂。 有时这是理想的解决方案。有时不是。与往常一样,基准测试。如果您捕获了 很多 错误的输入数据,那么崩溃可能是较轻的负载。如果 99% 的输入数据是好的,那么try..catch 可能会更好。
    猜你喜欢
    • 2019-11-15
    • 1970-01-01
    • 2020-03-13
    • 2015-02-21
    • 2020-12-19
    • 2021-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多