# \[SOLVED\] 37x performance hit when wrapping Refs. Any solution?

**URL:** <https://discourse.julialang.org/t/solved-37x-performance-hit-when-wrapping-refs-any-solution/61499>\
**Category:** Performance\
**Created:** [May 20, 2021, 7:16am UTC](https://discourse.julialang.org/t/solved-37x-performance-hit-when-wrapping-refs-any-solution/61499 "2021-05-20T07:16:55Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![fverdugo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fverdugo/32/9446_2.png) [@fverdugo](https://discourse.julialang.org/u/fverdugo)\
**Post date:** [May 20, 2021, 7:16am UTC](https://discourse.julialang.org/t/solved-37x-performance-hit-when-wrapping-refs-any-solution/61499/1 "2021-05-20T07:16:55Z")

</div>

## Problem

I have found that wrapping `Ref` instances in a `struct` leads to a sizable performance hit. Here a MWE:

```julia
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:

```julia-auto
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!

---

<div class="post-metadata">

**Author:** ![tomaklutfu](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomaklutfu/32/2411_2.png) [@tomaklutfu](https://discourse.julialang.org/u/tomaklutfu)\
**Post date:** [May 20, 2021, 8:17am UTC](https://discourse.julialang.org/t/solved-37x-performance-hit-when-wrapping-refs-any-solution/61499/2 "2021-05-20T08:17:48Z")

</div>

`Ref` is an abstract type so this is expected. The concrete type is `Base.RefValue{Int}` for `Ref{Int}(.)`. If you want to use ref value in a struct you can make it parametric to the ref value type for better alternative.

```julia
struct Foo{R}
  ref::R
  Foo(a::Int) = new(Ref(a))
end

```

---

<div class="post-metadata">

**Author:** ![fverdugo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fverdugo/32/9446_2.png) [@fverdugo](https://discourse.julialang.org/u/fverdugo)\
**Post date:** [May 20, 2021, 8:39am UTC](https://discourse.julialang.org/t/solved-37x-performance-hit-when-wrapping-refs-any-solution/61499/3 "2021-05-20T08:39:08Z")

</div>

@tomaklutfu Thanks for the (very useful) answer! I was completely unaware that `Ref` was an abstract type!
