Julia 中的错误处理 - “不推荐”异常的替代方案是什么?

问题描述 投票:0回答:1

以下引用摘自 Julia 文档

Julia 中的异常处理是使用

try — catch — finally
而不是
try — except — finally
完成的。与 Python 相比,不建议在 Julia 中将异常处理作为正常工作流程的一部分(与 Python 相比,Julia 在普通控制流方面更快,但在异常捕获方面较慢)。

这就提出了一个问题 - 在 Julia 程序中处理错误状态的推荐方法是什么?

我知道的其他方式

  1. 整数返回码,例如 C 中
  2. Result
    (或有时,
    Option
    )类型,例如 Rust

之前在此站点和其他地方都曾进行过讨论,深入讨论了为什么 (1) 是一个坏主意,但是 Julia 文档中的引用似乎表明在 Julia 程序中处理错误状态的推荐方法是返回任意整数错误代码。我觉得这很令人惊讶,并怀疑我的解释不正确。

error-handling julia
1个回答
0
投票

正如其他人所评论的,

try
catch
finally
流程的替代方案不是直接替代方案,而是预先重构代码以处理错误原因。

由于这是一个非具体的答案,因此对不同的控制流进行基准测试可能会有所帮助,以确定此重构是否值得重构的时间投资

下面是一个以两种方式编写的简单函数:一种使用

try
来检测越界错误,另一种使用
if
来避免越界错误。请注意,这些函数在局部变量大小、时间复杂度等方面具有可比性,它们唯一真正的区别是控制流的选择,其中“if 函数”需要一个额外的相等性检查。

julia> function useTry()
    count = 0
    sizeOfVector = 50
    myVector = zeros(sizeOfVector) .+ 1 # create a vector of ones
    for i in 1:100
        try # try to add the ith element to count
            count += myVector[i]
        catch # if i is out of bounds, do nothing
            nothing
        end
    end
    return count == 50
end
useTry (generic function with 1 method)

julia> function avoidTry()
    count = 0
    sizeOfVector = 50
    myVector = zeros(sizeOfVector) .+ 1 # create a vector of ones
    for i in 1:100
        if i <= sizeOfVector # if possible, add the ith element to count
            count += myVector[i]
        else # if i is out of bounds, do nothing
            nothing
        end
    end
    return count == 50
end

avoidTry (generic function with 1 method)

julia> using BenchmarkTools

julia> @btime useTry()
  308.300 μs (152 allocations: 4.88 KiB)
true

julia> @btime avoidTry()
  315.929 ns (2 allocations: 992 bytes)
true

因此,使用 BenchmarkTools 的

@btime
(本质上是内置
@time
的改进(平均多次运行)版本),
avoidTry
useTry
快 975.85 倍。现在,这里有一些重要的警告:运行时将根据设备和当前设备使用情况而有很大差异,并且这两个功能仍然具有相当的性能。话虽这么说,更大数量的分配表明不同设备之间可能存在类似的性能差异。

这个小测试虽然说明了问题,但并不是故事的全部。如果您想要进行与此类似的测试,则必须使用与您的预期用例类似的函数来测试运行时。希望这能让您相信 Julia 文档并没有在性能差异方面撒谎,并且在适用时可能会避免

try

© www.soinside.com 2019 - 2024. All rights reserved.