多次派遣返回值

时间:2014-03-09 22:44:44

标签: julia multiple-dispatch

我有一个例程,可以返回任何FloatingPoint类型的数组(或者实际上是任何数字类型,但它是用于浮点数)。它计算连续分数的收敛。我的问题是我希望编译器针对每种返回类型对其进行优化,例如: Float64,BigFloat等,而不是使用通用代码。

function floatconvergents(a::Vector{Int}, n_quotients::Int, t::Type)
    r = Array(t, n_quotients)
    u = Array(t, n_quotients)
    v = Array(t, n_quotients)
    r[1],u[1],v[1] = a[1],0,1
    for k=2:n_quotients
        u[k] = 1 / (a[k] + u[k-1])
        r[k] = (a[k]*r[k-1] + v[k-1]) * u[k]
        v[k] = r[k-1] * u[k]
    end
    return r
end

对我来说唯一可行的解​​决方案是将结果数组作为参数传递并使其成为参数函数

function floatconvergents!{T<:FloatingPoint}(a::Vector{Int}, n_quotients::Int, r::Vector{T})

我看到的唯一问题是除了指定其类型之外没有理由将结果数组作为参数提供。这似乎不是“正确”的事情。

1 个答案:

答案 0 :(得分:1)

这将调度类型,因此它将专门化代码:

function floatconvergents{T<:FloatingPoint}(a::Vector{Int}, n_quotients::Int, ::Type{T})
    r = Array(T, n_quotients)
    u = Array(T, n_quotients)
    v = Array(T, n_quotients)
    r[1],u[1],v[1] = a[1],0,1
    for k=2:n_quotients
        u[k] = 1 / (a[k] + u[k-1])
        r[k] = (a[k]*r[k-1] + v[k-1]) * u[k]
        v[k] = r[k-1] * u[k]
    end
    return r
end

例如,可以通过floatconvergents(some_vector, some_int, Float64)来调用它。

证明:

julia> f{T<:FloatingPoint}(::Type{T}) = T===Float64 ? 1 : 0
julia> code_llvm(f, (Type{Float64},))
define i64 @julia_f15644(%jl_value_t*) {
top:
  ret i64 1, !dbg !2042
}
julia> code_llvm(f, (Type{BigFloat},))
define i64 @julia_f15645(%jl_value_t*) {
top:
  ret i64 0, !dbg !2045
}