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?
Mason
May 22, 2020, 8:29pm
2
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