Hi. I’ve defined some parametric structs like those defined in the Performance Tips section of the Julia manual. Since some of the structs had quite long names, I decided to alias them.
I was struggling to wrap my head around why @btime
was so slow and why @code_warntype
was giving me errors when I had the thought to try using the longer names for the structs. Lo and behold, type-stability was achieved.
Is this correct Julia behavior, and if so, is it documented anywhere? Or have I just not yet read the manual enough?
struct LongStructName{T<:Integer}
i::T
end
ShStruct = LongStructName
# Check that they are totally equal
julia> ShStruct === LongStructName
true
# Use constructors in separate function
function create_objects(a::Integer, b::Integer)
return LongStructName(a), LongStructName(b)
end
function create_objects_alias(a::Integer, b::Integer)
return ShStruct(a), ShStruct(b)
end
julia> @code_warntype create_objects(1, 2)
Variables
#self#::Core.Compiler.Const(create_objects, false)
a::Int64
b::Int64
Body::Tuple{LongStructName{Int64},LongStructName{Int64}}
1 ─ %1 = Main.LongStructName(a)::LongStructName{Int64}
│ %2 = Main.LongStructName(b)::LongStructName{Int64}
│ %3 = Core.tuple(%1, %2)::Tuple{LongStructName{Int64},LongStructName{Int64}}
└── return %3
# Aliased name breaks type-stability
julia> @code_warntype create_objects_alias(1, 2)
Variables
#self#::Core.Compiler.Const(create_objects_alias, false)
a::Int64
b::Int64
Body::Tuple{Any,Any}
1 ─ %1 = Main.ShStruct(a)::Any
│ %2 = Main.ShStruct(b)::Any
│ %3 = Core.tuple(%1, %2)::Tuple{Any,Any}
└── return %
# Raw constructors do not give errors
julia> @code_warntype ShStruct(1)
Variables
#self#::Type{LongStructName}
i::Int64
Body::LongStructName{Int64}
1 ─ %1 = Core.apply_type(Main.LongStructName, $(Expr(:static_parameter, 1)))::Core.Compiler.Const(LongStructName{Int64}, false)
│ %2 = (%1)(i)::LongStructName{Int64}
└── return %2
julia> @code_warntype ShStruct(1)
Variables
#self#::Type{LongStructName}
i::Int64
Body::LongStructName{Int64}
1 ─ %1 = Core.apply_type(Main.LongStructName, $(Expr(:static_parameter, 1)))::Core.Compiler.Const(LongStructName{Int64}, false)
│ %2 = (%1)(i)::LongStructName{Int64}
└── return %2