Julia 1.1.0 on macOS mojave
In the following example, I’d expect branch elimination to make both of the following type stable, however getproperty
isn’t type stable and is allocating. Could someone shed some light on why this is happening?
mutable struct Entry
id::Int
data::Vector{Float64}
end
function Base.getproperty(e::Entry, s::Symbol)
if s === :value
e.data[e.id]
else
getfield(e, s)
end
end
function Base.setproperty!(e::Entry, s::Symbol, c)
if s === :value
e.data[e.id] = c
else
setfield!(e, s, c)
end
end
function example_read(e)
e.value
end
function example_write(e)
e.value = 0.0
end
function main()
storage = randn(1000000)
entry = Entry(123, storage)
@code_warntype example_read(entry)
@code_warntype example_write(entry)
end
main()
Which results in
Body::Union{Float64, Int64, Array{Float64,1}}
1 ─ %1 = invoke Base.getproperty(_2::Entry, :value::Symbol)::Union{Float64, Int64, Array{Float64,1}}
└── return %1
Body::Float64
1 ─ goto #3 if not false
2 ─ nothing
3 ┄ %3 = (Main.getfield)(e, :data)::Array{Float64,1}
│ %4 = (Main.getfield)(e, :id)::Int64
│ (Base.arrayset)(true, %3, 0.0, %4)
└── return 0.0
(you’ll have to trust me that the improvement in the user interface for my use case is worth the effort here. This is just a minimal example)
How can I make the above type stable?