I’m trying to understand type stability when accessing composite types.
Consider the custom datatype:
struct MyStruct
a::Int
b::Number
c::AbstractDict
end
I create an instance,
obj = MyStruct(1, 2.0, Dict())
Running @code_warntype
on obj.a
shows that getproperty
is not type stable:
julia> @code_warntype obj.a
MethodInstance for getproperty(::MyStruct, ::Symbol)
from getproperty(x, f::Symbol) in Base at Base.jl:38
Arguments
#self#::Core.Const(getproperty)
x::MyStruct
f::Symbol
Body::Any
1 ─ nothing
│ %2 = Base.getfield(x, f)::Any
└── return %2
of course, ::Any
is highlighted in red in the REPL.
Next, if I try @code_warntype
on getfield
, I get this:
julia> @code_warntype getfield(obj, :a)
getfield(...) in Core
failed to infer
When passing such objects as arguments to functions which access their properties, obviously the type instability is resolved somehow when the function attempts to access obj.a
. For example,
julia> function g(x) x.a+1 end
julia> @code_warntype g(obj)
MethodInstance for g(::MyStruct)
from g(x) in Main at REPL[9]:1
Arguments
#self#::Core.Const(g)
x::MyStruct
Body::Int64
1 ─ %1 = Base.getproperty(x, :a)::Int64
│ %2 = (%1 + 1)::Int64
└── return %2
What’s happening here? I’ve tried to look for applicable definitions of getproperty
and getfield
to see how the type instability is resolved, but so far I couldn’t seem to find them.
Thanks~