【问题标题】:How to write a memoizer that is type inference friendly如何编写类型推断友好的记忆器
【发布时间】:2017-04-05 18:26:17
【问题描述】:
function memoize(f, T)
    cache = Dict{Any, T}()
    function g(args...)::T
        key = make_key(args...)
        get!(cache, key) do
            f(args...)
        end
    end
    g
end

fib = memoize(x::Int -> begin
    if x == 2
        return 2 
    end
    if x == 1
        return 1
    end
    fib(x - 1) + fib(x - 2)
end, Int)

这就是我得到的,遗憾的是它无法识别返回类型,尽管我注释了。

另外,有没有办法注释匿名函数的返回类型?

@code_warntype fib(3)

Variables:
  #self#::#g#40{##44#45,DataType,Dict{Any,Int64}}
  args::Tuple{Int64}
  key::Tuple{Int64}
  #39::##39#41{Tuple{Int64},##44#45}

Body:
  begin 
      SSAValue(0) = (Core.getfield)(#self#::#g#40{##44#45,DataType,Dict{Any,Int64}},:T)::DataType
      key::Tuple{Int64} = (Core.tuple)((Core.getfield)(args::Tuple{Int64},1)::Int64)::Tuple{Int64} # line 20:
      #39::##39#41{Tuple{Int64},##44#45} = $(Expr(:new, ##39#41{Tuple{Int64},##44#45}, :(args), :((Core.getfield)(#self#,:f)::##44#45)))
      SSAValue(1) = #39::##39#41{Tuple{Int64},##44#45}
      SSAValue(2) = (Core.getfield)(#self#::#g#40{##44#45,DataType,Dict{Any,Int64}},:cache)::Dict{Any,Int64}
      return (Core.typeassert)((Base.convert)(SSAValue(0),$(Expr(:invoke, LambdaInfo for get!(::##39#41{Tuple{Int64},##44#45}, ::Dict{Any,Int64}, ::Tuple{Int64}), :(Main.get!), SSAValue(1), SSAValue(2), :(key))))::ANY,SSAValue(0))::ANY
  end::ANY

更新

我制作了一个包,它通过宏为类型推断友好的通用函数记忆提供基本支持。它还允许从函数参数中自定义缓存键。

https://github.com/colinfang/Memoize.jl

【问题讨论】:

标签: julia


【解决方案1】:

为了让 Julia 专门针对特定的 DataType 实现其实现,您必须使用 ::Type{T} 参数类型:

function memoize{T}(f, ::Type{T})
    …

这个简单的改变意味着 Julia 将为 memoize 遇到的每一种类型专门化方法,而不是只为所有 DataTypes 专门化一种方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-08-22
    • 1970-01-01
    • 1970-01-01
    • 2023-03-24
    • 1970-01-01
    • 2010-10-03
    • 2011-12-13
    • 1970-01-01
    相关资源
    最近更新 更多