Inspired by this post I wanted to add extra properties to my type, but noted a significant performance hit:
julia> using BenchmarkTools
julia> struct AType{T}
data::T
end
julia> struct BType{T}
data::T
end
julia> _getproperty(x::AType, ::Val{s}) where {s} = getfield(x, s)
julia> _getproperty(x::AType, ::Val{:two}) = 2*x.data
julia> Base.getproperty(x::AType, s::Symbol) = _getproperty(x, Val{s}())
julia> a = AType(1.0)
julia> b = BType(1.0)
julia> @benchmark b.data
BenchmarkTools.Trial:
memory estimate: 48 bytes
allocs estimate: 3
--------------
minimum time: 69.511 ns (0.00% GC)
median time: 73.613 ns (0.00% GC)
mean time: 78.808 ns (2.21% GC)
maximum time: 1.978 μs (95.25% GC)
--------------
samples: 10000
evals/sample: 977
julia> @benchmark a.data
BenchmarkTools.Trial:
memory estimate: 48 bytes
allocs estimate: 3
--------------
minimum time: 5.675 μs (0.00% GC)
median time: 5.855 μs (0.00% GC)
mean time: 5.909 μs (0.00% GC)
maximum time: 13.520 μs (0.00% GC)
--------------
samples: 10000
evals/sample: 6
As you can see, adding a custom getproperty(x::AType, ...)
function makes accessing all properties (not only .two
) much (almost 100x) slower. Are there other, more clever ways to overload getproperty
, or will checking the value of s
cost me performance, no matter what?