朱莉娅 - @code_warntype问题与ProgressMeter

3

使用 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个回答

4
这是Julia中for循环的内部运行方式,您不需要担心或修复任何问题,在这里可以查看详细信息:https://docs.julialang.org/en/v1/manual/interfaces/#man-interface-iteration-1
特别地,for循环在迭代对象上调用iterate,并在迭代器完成时返回nothing或一个包含loopvariable和state的元组。对于这种特殊情况,从StepRange{Int,Int}的iterate调用中,您将得到Union{Nothing, Tuple{Int,Int}}:
julia> @code_warntype iterate(3:5:20)
Body::Union{Nothing, Tuple{Int64,Int64}}
[...]

3
谢谢您的回答。在我选择您的答案之前,我想问一下,当code_warntype返回红色类型时,如何知道什么时候不必担心,什么时候需要担心? - JKHA
3
这个 Union 特别标记为黄色,而不是红色,这意味着它“可能不是一个坏事”。特别是 "small unions" 带有 singleton 类型通常不是问题,例如 Union{Missing, X}Union{Nothing, X}。其它故意返回联合类型的例子包括 find* 系列函数。参见 https://julialang.org/blog/2018/08/union-splitting - fredrikekre

1
你可以选择使用 while 循环。它们不会返回小的联合体。 更新:这样做可能会过度劳累。@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
    4return

    @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
    4return

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接