How can I improve this? I want to keep the Union{A,B,C,D}
but make it faster. JET says c
is captured and also there is runtime dispatch.
abstract type T end
struct A <: T x::Int end
struct B <: T x::Int end
struct C <: T x::Int end
struct D <: T x::Int end
f() = rand((A,B,C,D))(1)
function g(n)
local c::Int = 0
foreach(1:n) do _
y = f()::Union{A,B,C,D}
if y isa A
c += 1
elseif y isa B
c += 2
elseif y isa C
c += 3
elseif y isa D
c += 4
else
error("unreachable")
end
end
c
end
@report_opt g(10)
MethodInstance for g(::Int64)
from g(n) @ Main
Arguments
#self#::Core.Const(g)
n::Int64
Locals
#65::var"#65#66"
c@_4::Core.Box
@_5::Int64
c@_6::Union{}
Body::Int64
1 β Core.NewvarNode(:(#65))
β (c@_4 = Core.Box())
β %3 = c@_4::Core.Box
β (@_5 = 0)
β %5 = (@_5::Core.Const(0) isa Main.Int)::Core.Const(true)
βββ goto #3 if not %5
2 β goto #4
3 β Core.Const(:(Base.convert(Main.Int, @_5)))
βββ Core.Const(:(@_5 = Core.typeassert(%8, Main.Int)))
4 β %10 = @_5::Core.Const(0)
β Core.setfield!(%3, :contents, %10)
β (#65 = %new(Main.:(var"#65#66"), c@_4))
β %13 = #65::var"#65#66"
β %14 = (1:n)::Core.PartialStruct(UnitRange{Int64}, Any[Core.Const(1), Int64])
β Main.foreach(%13, %14)
β %16 = Core.isdefined(c@_4, :contents)::Bool
βββ goto #6 if not %16
5 β goto #7
6 β Core.NewvarNode(:(c@_6))
βββ c@_6
7 β %21 = Core.getfield(c@_4, :contents)::Any
β %22 = Core.typeassert(%21, Main.Int)::Int64
βββ return %22