Changing field with a function in a mutable struct

Not sure why you need the function type in the type signature of your struct. But if that isn’t essential then this alternative will work:

mutable struct Foo{T<:Real}
    a::T
    f::Function
end

Foo is a concrete type so I would expect it to be efficient:

julia> foo = Foo(1,bar)
Foo{Int64}(1, var"#9#10"())

julia> foo.f = baz
#11 (generic function with 1 method)

julia> isconcretetype(typeof(foo))
true

@code_warntype suggests there might be a type instability but @code_llvm and @code_native both look very efficient.

This function benchmarks well

f(a,f1,f2) = (a.f === f1) ? a.f = f2 : a.f = f1

julia> @benchmark f($foo,$bar,$baz)
BenchmarkTools.Trial: 10000 samples with 1000 evaluations.
 Range (min … max):  1.800 ns … 23.100 ns  ┊ GC (min … max): 0.00% … 0.00%
 Time  (median):     2.100 ns              ┊ GC (median):    0.00%
 Time  (mean ± σ):   2.161 ns ±  0.499 ns  ┊ GC (mean ± σ):  0.00% ± 0.00%

  ▅  ▄      █   ▄   ▄  ▅          ▁          ▁               ▁
  █▁▁█▁▁▁█▁▁█▁▁▁█▁▁▁█▁▁█▁▁▁▇▁▁█▁▁▁█▁▁▁▅▁▁▆▁▁▁█▁▁▁▁▁▁▃▁▁▁▅▁▁▆ █
  1.8 ns       Histogram: log(frequency) by time      3.4 ns <

 Memory estimate: 0 bytes, allocs estimate: 0.

so it looks like the compiler is generating efficient code for accessing the function field.

5 Likes