Getproperty optimization in struct

I have the following code (example):

struct Foo{N}
    t :: NTuple{N, Int}
end

foo = Foo((1,2,3))

Now if I try to get access to t field, I have some unnecessary allocations:

using BenchmarkTools
@benchmark getproperty(foo, :t)

How it can be avoided?

You’re not benchmarking getproperty, you’re benchmarking the overhead of resolving a global variable.

Here’s a more realistic benchmark of what I think you’re trying to measure:

struct Foo{N}
    t :: NTuple{N, Int}
end

foo = Foo((1,2,3))

julia> @benchmark getproperty($(Ref(foo))[], :t)
BenchmarkTools.Trial: 
  memory estimate:  0 bytes
  allocs estimate:  0
  --------------
  minimum time:     1.299 ns (0.00% GC)
  median time:      1.340 ns (0.00% GC)
  mean time:        1.339 ns (0.00% GC)
  maximum time:     6.780 ns (0.00% GC)
  --------------
  samples:          10000
  evals/sample:     1000

If you want to measure the case where the compiler has an opportunity to know not just the type, but the contents of foo at compile time then you can do

julia> @benchmark getproperty($foo, :t)
BenchmarkTools.Trial: 
  memory estimate:  0 bytes
  allocs estimate:  0
  --------------
  minimum time:     0.020 ns (0.00% GC)
  median time:      0.020 ns (0.00% GC)
  mean time:        0.024 ns (0.00% GC)
  maximum time:     0.130 ns (0.00% GC)
  --------------
  samples:          10000
  evals/sample:     1000

which just says that the compiler was able to completely elide the operation and do nothing. (sub ns timings basically always means that it was a no-op)

1 Like