Julia-ProgressMeter的@code_warntype问题

时间:2019-06-03 09:27:12

标签: performance for-loop progress-bar julia

using ProgressMeter中使用此for循环:

function test()
       @showprogress 1 "Computing..." for n in 3:5:20
           print()
       end
 end

我不明白为什么@code_warntype test()在三行返回类型警告,最重要的是如何解决它:

 %18 = φ (#2 => %12, #3 => %14)::Union{Nothing, Tuple{Int64,Int64}}

2 个答案:

答案 0 :(得分:2)

这是for循环在Julia内部的工作方式,您无需担心或在这里解决,请参见https://docs.julialang.org/en/v1/manual/interfaces/#man-interface-iteration-1

尤其是,for循环在您迭代的对象上调用iterate,如果迭代器完成,则返回nothing,或者返回带有loopvariable, state的元组。对于这种特殊情况,iterate中的StepRange{Int,Int}会从Union{Nothing, Tuple{Int,Int}}调用中返回iterate

julia> @code_warntype iterate(3:5:20)
Body::Union{Nothing, Tuple{Int64,Int64}}
[...]

答案 1 :(得分:0)

您可以使用while循环。他们不返回小工会。 UPD:这样做可能会过度工作。 @code_native表示实现之间没有区别。而不是外部循环,我将重点放在使类型稳定的昂贵函数调用上。

    function f()
       for i=1:12
       end
    end
    function g()
        i=1
        while i<13
            i+=1
        end
    end
    @code_warntype f()

    Variables
    #self#::Core.Compiler.Const(f, false)
    @_2::Union{Nothing, Tuple{Int64,Int64}}
    i::Int64

    Body::Nothing
    1 ─ %1  = (1:12)::Core.Compiler.Const(1:12, false)
    │         (@_2 = Base.iterate(%1))
    │   %3  = (@_2::Core.Compiler.Const((1, 1), false) === 
    nothing)::Core.Compiler.Const(false, false)
    │   %4  = Base.not_int(%3)::Core.Compiler.Const(true, false)
    └──       goto #4 if not %4
    2 ┄ %6  = @_2::Tuple{Int64,Int64}::Tuple{Int64,Int64}
    │         (i = Core.getfield(%6, 1))
    │   %8  = Core.getfield(%6, 2)::Int64
    │         (@_2 = Base.iterate(%1, %8))
    │   %10 = (@_2 === nothing)::Bool
    │   %11 = Base.not_int(%10)::Bool
    └──       goto #4 if not %11
    3 ─       goto #2
    4 ┄       return

    @code_warntype g()

    Variables
    #self#::Core.Compiler.Const(g, false)
    i::Int64

    Body::Nothing
    1 ─      (i = 1)
    2 ┄ %2 = (i < 13)::Bool
    └──      goto #4 if not %2
    3 ─      (i = i + 1)
    └──      goto #2
    4 ─      return