# Why the performance hit on this trivial vector wrapper broadcast?

**URL:** <https://discourse.julialang.org/t/why-the-performance-hit-on-this-trivial-vector-wrapper-broadcast/25335>\
**Category:** General Usage\
**Created:** [June 15, 2019, 9:52pm UTC](https://discourse.julialang.org/t/why-the-performance-hit-on-this-trivial-vector-wrapper-broadcast/25335 "2019-06-15T21:52:58Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![marius311](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marius311/32/3953_2.png) [@marius311](https://discourse.julialang.org/u/marius311)\
**Post date:** [June 15, 2019, 9:52pm UTC](https://discourse.julialang.org/t/why-the-performance-hit-on-this-trivial-vector-wrapper-broadcast/25335/1 "2019-06-15T21:52:58Z")

</div>

I’ve got a trivial vector wrapper type implementing a minimal [array interface](https://docs.julialang.org/en/v1.1/manual/interfaces/#man-interface-array-1):

```julia
using Lazy

struct VecWrapper{T, V<:AbstractVector{T}} <: AbstractVector{T}
    data :: V
end
@forward VecWrapper.data (Base.getindex, Base.setindex!, Base.size)

```

however I see a ~10% performance hit in broadcasting:

```julia
using BenchmarkTools

v = rand(512^2)
vw = VecWrapper(v)

@benchmark $v .+ $v # 268.017 μs
@benchmark $vw .+ $vw # 297.195 μs

```

Any ideas where this is coming from, or how I can get rid of it? I’m on Julia 1.1. Thanks.

---

<div class="post-metadata">

**Author:** ![Elrod](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/elrod/32/22461_2.png) [@Elrod](https://discourse.julialang.org/u/Elrod)\
**Post date:** [June 15, 2019, 11:16pm UTC](https://discourse.julialang.org/t/why-the-performance-hit-on-this-trivial-vector-wrapper-broadcast/25335/2 "2019-06-15T23:16:20Z")

</div>

Base.@propagate\_inbounds Base.getindex(vw::VecWrapper, i) = vw.data[i]

With that modification,

```julia
julia> vpv = v .+ v;

julia> @benchmark $vpv .= $v .+ $v # 268.017 μs
BenchmarkTools.Trial: 
  memory estimate: 0 bytes
  allocs estimate: 0
  --------------
  minimum time: 154.436 μs (0.00% GC)
  median time: 155.591 μs (0.00% GC)
  mean time: 158.077 μs (0.00% GC)
  maximum time: 319.513 μs (0.00% GC)
  --------------
  samples: 10000
  evals/sample: 1

julia> @benchmark $vpv .= $vw .+ $vw # 268.017 μs
BenchmarkTools.Trial: 
  memory estimate: 0 bytes
  allocs estimate: 0
  --------------
  minimum time: 154.587 μs (0.00% GC)
  median time: 155.770 μs (0.00% GC)
  mean time: 157.691 μs (0.00% GC)
  maximum time: 309.811 μs (0.00% GC)
  --------------
  samples: 10000
  evals/sample: 1

```

You will probably want to define `setindex!` and any other function that cares about bounds checks similarly.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [June 16, 2019, 6:06am UTC](https://discourse.julialang.org/t/why-the-performance-hit-on-this-trivial-vector-wrapper-broadcast/25335/3 "2019-06-16T06:06:06Z")

</div>

Here is the detailed documentation to complement @Elrod’s excellent answer:

[https://docs.julialang.org/en/v1.3-dev/devdocs/boundscheck/](https://docs.julialang.org/en/v1.3-dev/devdocs/boundscheck/)

---

<div class="post-metadata">

**Author:** ![marius311](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marius311/32/3953_2.png) [@marius311](https://discourse.julialang.org/u/marius311)\
**Post date:** [June 17, 2019, 12:56am UTC](https://discourse.julialang.org/t/why-the-performance-hit-on-this-trivial-vector-wrapper-broadcast/25335/4 "2019-06-17T00:56:20Z")

</div>

Excellent answer, thanks! I should have remember about `@propagate_inbounds`.
