I’m trying to access linked entries in a sparse matrix where only the values change and thought it would be faster to save the locations of the values, but accessing them like this is much slower than just matrix indexing the sparse matrix and setting the values by hand. Inspecting with `@code_warntype`

reveals a lot of red lines.

I made the type

```
mutable struct Observer{T,R}
ref::R
pair::Pair{Int32,Int32}
nzidx1::Int32
nzidx2::Int32
val::T
end
```

Which I for example initialize as

```
sp # Some SparseMatrixCSC
ob = Observer(sp, 1=>2, 1, 101, sp.nzval[1])
@code_warntype ob.ref
MethodInstance for getproperty(::Observer{Float32, SparseMatrixCSC{Float32, Int32}}, ::Symbol)
from getproperty(x, f::Symbol) @ Base Base.jl:37
Arguments
#self#::Core.Const(getproperty)
x::Observer{Float32, SparseMatrixCSC{Float32, Int32}}
f::Symbol
Body::Any
1 ─ nothing
│ %2 = Base.getfield(x, f)::Any
└── return %2
```

Get field seems to be type instable?

Then I’m trying to set them through a dict of these things, and `@code_warntype`

reveals a lot of red.

```
function setval(ob::Observer, val)
ob.ref.nzval[ob.nzidx1] = val
ob.ref.nzval[ob.nzidx2] = val
end
struct ObserverList{A, B} <: AbstractDict{A, B}
observers::Dict{A, B}
end
function setval(obs::ObserverList{A,Observer{T,R}}, val, pair) where {A, T, R<:SparseMatrixCSC{T}}
if haskey(obs, pair)
setval(obs[pair], val)
return val
end
return val
end
@code_warntype setval(observers,1, 1=>2)
MethodInstance for setval(::ObserverList{Pair{Int32, Int32}, Observer{Float32}}, ::Int64, ::Pair{Int32, Int32})
from setval(obs::ObserverList, val, pair) @ Main ~/Documents/GitHub/InteractiveRBM.jl/ObserverList.jl:41
Arguments
#self#::Core.Const(setval)
obs::ObserverList{Pair{Int32, Int32}, Observer{Float32}}
val::Int64
pair::Pair{Int32, Int32}
Locals
observer::Observer{Float32}
Body::Union{Nothing, Int64}
1 ─ Core.NewvarNode(:(observer))
│ %2 = Main.haskey(obs, pair)::Bool
└── goto #3 if not %2
2 ─ (observer = Base.getindex(obs, pair))
│ %5 = Base.getproperty(observer, :ref)::SparseMatrixCSC
│ %6 = Base.getproperty(%5, :nzval)::Vector
│ %7 = Base.getproperty(observer, :nzidx1)::Int32
│ Base.setindex!(%6, val, %7)
│ %9 = Base.getproperty(observer, :ref)::SparseMatrixCSC
│ %10 = Base.getproperty(%9, :nzval)::Vector
│ %11 = Base.getproperty(observer, :nzidx2)::Int32
│ Base.setindex!(%10, val, %11)
└── return val
3 ─ return
```

I’m open to this being a dumb idea, but I am genuinely a bit confused why the code ends up being type instable…