【发布时间】:2016-05-10 16:29:13
【问题描述】:
我了解 Julia 严重依赖即时静态类型派生(基本上所有代码都需要被视为 c++ 模板)。我也明白这意味着在对不同类型的对象使用单一算法时没有运行时开销,只要这些类型在编译时是已知的。
当谈到运行时多态性时,我不太清楚事情是如何工作的。假设我们有以下情况:
abstract Shape
type Circle <: Shape
radius::Float64
end
type Square <: Shape
width::Float64
end
dist(x::Circle, y::Circle) = ...
dist(x::Circle, y::Square) = ...
dist(x::Square, y::Circle) = ...
dist(x::Square, y::Square) = ...
s = get_shape()
t = get_shape()
a = dist(s,t)
在这里,get_shape 可以返回圆形或正方形,例如基于用户输入。在 C++ 中,分派将简单地进行虚拟表查找。这在 Julia 中是如何工作的?多重调度背后的机制是什么?它比虚拟表查找贵得多吗?从同一个抽象类型派生Square 和Circle 有什么好处,或者这与运行时调度的上下文完全无关?
EDT:在此示例上运行 @code_warntype 给出:
Variables:
s::Union{Circle,Square}
t::Union{Circle,Square}
Body:
begin # none, line 2:
s = (Main.get_shape)()::Union{Circle,Square} # none, line 3:
t = (Main.get_shape)()::Union{Circle,Square} # none, line 4:
return (Main.dist)(s::Union{Circle,Square},t::Union{Circle,Square})::ASCIIString
end::ASCIIString
所以编译器并不是完全不知道 s 和 t 的类型。调用dist时,这些知识是否用于加快调度?
【问题讨论】:
-
如果我不得不在这种情况下猜测自己(编译时类型是复合类型的联合),我会说编译器生成了四个虚拟表(对于四种可能的类型组合)并且随后的运行时调度在速度上与 c++' 相当。听起来对吗?
标签: performance polymorphism julia