Problem
I have found that wrapping Ref
instances in a struct
leads to a sizable performance hit. Here a MWE:
using BenchmarkTools
struct Foo
ref::Ref{Int}
Foo(a::Int) = new(Ref(a))
end
work(i,ref::Ref) = sqrt(i*ref[])
@noinline work(i,foo::Foo) = work(i,foo.ref)
function loop(n,x)
q = 0.0
for i in 1:n
for j in 1:10
q += work(i,x)
end
end
q
end
function main(n)
foo= Foo(2)
println("Benchmark for Foo:")
@btime loop($n,$foo)
ref = Ref(2)
println("Benchmark for Ref:")
@btime loop($n,$ref)
end
main(1000000)
which gives this output:
Benchmark for Foo:
832.085 ms (29994890 allocations: 457.69 MiB)
Benchmark for Ref:
22.336 ms (0 allocations: 0 bytes)
Note that using the simple wrapper Foo
leads to a 37x time increase wrt using the plain Ref
.
Question
Is anybody aware of this? Is there any solution/workaround to this problem?
Thanks in advance for helping!