gpt4 book ai didi

julia - 在 Julia 中,如何正确地对调用者提供的(超)类型的参数进行方法分派(dispatch)?

转载 作者:行者123 更新时间:2023-12-03 14:30:06 26 4
gpt4 key购买 nike

我想定义一个函数f(x, t::Type)根据 isa(x, t) 是否执行不同的行为.假设我想调用b1(x)如果是,b2(x)除此以外。

我知道我可以像这样在运行时进行动态检查:

function f(x, t::Type)
if isa(x, t)
b1(x)
else
b2(x)
end
end

但是,有没有办法纯粹通过参数方法调度来做到这一点?例如,如果我定义
f{T}(x::T, t::Type{T}) = b1(x)
f(x, t::Type) = b2(x)

对于 f(1, Int)f(1.0, Int)调用正确的行为。但我希望这也适用于 t 的所有子类型:
f(1, Number)

这实际上调用了 b2因为 f的第一个签名不匹配。有趣的是, f(x::Number, t::Type{Number}) = b1(x)在这种情况下会匹配。

我在这里遗漏了一些明显的东西吗?

这显然是一个错误,并在 0.4 中修复。

问题:
  • 为什么f{T}(x::T, t::Type{T})不匹配 f(1, Number) , 即使有 T 的类型替换( Number ) 那会匹配吗?
  • 使用 f{T2, T1 <: T2}(x::T1, t::Type{T2})或类似的东西不起作用,因为似乎所有静态参数只有在完整的静态参数列表关闭后才进入范围。为什么?
  • 使用动态方法是否有任何性能损失?
  • 将方法定义为内部函数怎么样,所以我可以绑定(bind) t到一个局部变量,像这样:function f(x, t::Type); g(x::t) = b1(x); g(x) = b2(x); g(x) end
    这行得通,但性能成本是多少?
  • 解决这个问题的惯用/首选方法是什么?

  • (我在 0.3.2 上试过这个。)

    最佳答案

    要回答您的问题:

  • AFAICT 它应该。正如 user3580870 评论的那样,这似乎在 Julia 0.4 中有效。
  • 这是“三角调度”,(尚未)实现。见 #3766 .
  • 依靠。编译器可以评估 isa(x, t)在编译时并消除分支。但是,仍有一些可能的方法使用 isa可能不是最理想的:
  • 如果两个分支返回不同的类型,类型推断将无法正确推断返回类型,因为它发生在 isa(x, t) 之前。被制成一个常数。 (这可能代价高昂;下面其他可能的去优化可能没什么大不了的。)
  • 如果一个分支执行堆分配而另一个不执行,则可能会发出不必要的 GC 帧。
  • 该函数可能未内联。
  • 内部函数将具有与使用 isa 相同的性能问题。和更多。从 Julia 0.5 开始,在这种情况下,内部函数应该与顶级函数一样高效。
  • 提交错误;-)。我认为这应该有效。有可能在 0.4 中修复此问题的任何内容都可以向后移植到 0.3。但如果做不到这一点,isa只要它不会导致类型推断问题,这不是一个坏方法。
  • 关于julia - 在 Julia 中,如何正确地对调用者提供的(超)类型的参数进行方法分派(dispatch)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26847790/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com