# Why is there memory allocation and time difference in @views and view?

**URL:** <https://discourse.julialang.org/t/why-is-there-memory-allocation-and-time-difference-in-views-and-view/58149>\
**Category:** Performance\
**Tags:** memory-allocation\
**Created:** [March 29, 2021, 7:13am UTC](https://discourse.julialang.org/t/why-is-there-memory-allocation-and-time-difference-in-views-and-view/58149 "2021-03-29T07:13:20Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![Shuhua](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/shuhua/32/27618_2.png) [@Shuhua](https://discourse.julialang.org/u/Shuhua)\
**Post date:** [March 29, 2021, 7:13am UTC](https://discourse.julialang.org/t/why-is-there-memory-allocation-and-time-difference-in-views-and-view/58149/1 "2021-03-29T07:13:21Z")

</div>

Julia Version 1.5.3

```julia
julia> f(a, b, c) = a + b - c;

julia> X = randn(1000, 5);

julia> y = zeros(1000);

# feed the last three columns of `X` into `f` and write the result into `y`

julia> @btime $y .= f((view($X, :, j) for j = 3:5)...);
  1.922 μs (9 allocations: 16.23 KiB)

julia> @btime $y .= @views f(($X[:, j] for j = 3:5)...);
  1.922 μs (9 allocations: 16.23 KiB)

```

I have three questions:

1. What causes the large memory allocation in both cases?
2. ~~Why is there a significant time difference between `view` and `@views`?~~ ([updated] Due to the error mentioned by @sijo 😅 )
3. What is the recommended way to achieve the above goal, i.e., broadcasting over multiple columns of a matrix?

---

<div class="post-metadata">

**Author:** ![sijo](https://avatars.discourse-cdn.com/v4/letter/s/da6949/32.png) [@sijo](https://discourse.julialang.org/u/sijo)\
**Post date:** [March 29, 2021, 7:45am UTC](https://discourse.julialang.org/t/why-is-there-memory-allocation-and-time-difference-in-views-and-view/58149/2 "2021-03-29T07:45:08Z")

</div>

You forgot to interpolate `X` in the first case 🙂

---

<div class="post-metadata">

**Author:** ![carstenbauer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/carstenbauer/32/4981_2.png) [@carstenbauer](https://discourse.julialang.org/u/carstenbauer)\
**Post date:** [March 29, 2021, 7:45am UTC](https://discourse.julialang.org/t/why-is-there-memory-allocation-and-time-difference-in-views-and-view/58149/3 "2021-03-29T07:45:44Z")

</div>

First thing to note, you’re interpolating the value of `X` in the second but not the first case.

```julia
julia> @btime $y .= f((view($X, :, j) for j = 3:5)...);
  1.234 μs (2 allocations: 15.88 KiB)

julia> @btime $y .= @views f(($X[:, j] for j = 3:5)...);
  1.127 μs (2 allocations: 15.88 KiB)

```

You might leave away the interpolation altogether and do

```julia
julia> @btime y .= f((view(X, :, j) for j = 3:5)...) setup=(X = randn(1000, 5); y = rand(1000););
  1.347 μs (2 allocations: 15.88 KiB)

julia> @btime y .= @views(f((X[:,j] for j = 3:5)...)) setup=(X = randn(1000, 5); y = rand(1000););
  1.186 μs (2 allocations: 15.88 KiB)

```

(This is on Julia 1.6.)

---

<div class="post-metadata">

**Author:** ![sijo](https://avatars.discourse-cdn.com/v4/letter/s/da6949/32.png) [@sijo](https://discourse.julialang.org/u/sijo)\
**Post date:** [March 29, 2021, 7:51am UTC](https://discourse.julialang.org/t/why-is-there-memory-allocation-and-time-difference-in-views-and-view/58149/4 "2021-03-29T07:51:24Z")

</div>

Note that you need 1.6 to get only 2 allocations… On 1.5.3 I get 11.

---

<div class="post-metadata">

**Author:** ![Shuhua](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/shuhua/32/27618_2.png) [@Shuhua](https://discourse.julialang.org/u/Shuhua)\
**Post date:** [March 29, 2021, 7:51am UTC](https://discourse.julialang.org/t/why-is-there-memory-allocation-and-time-difference-in-views-and-view/58149/5 "2021-03-29T07:51:52Z")

</div>

Thanks. But I cannot understand where the `2 allocations: 15.88 KiB` comes.

---

<div class="post-metadata">

**Author:** ![carstenbauer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/carstenbauer/32/4981_2.png) [@carstenbauer](https://discourse.julialang.org/u/carstenbauer)\
**Post date:** [March 29, 2021, 7:52am UTC](https://discourse.julialang.org/t/why-is-there-memory-allocation-and-time-difference-in-views-and-view/58149/6 "2021-03-29T07:52:12Z")

</div>

See @sijo’s comment. I’m running Julia 1.6.

---

<div class="post-metadata">

**Author:** ![sijo](https://avatars.discourse-cdn.com/v4/letter/s/da6949/32.png) [@sijo](https://discourse.julialang.org/u/sijo)\
**Post date:** [March 29, 2021, 7:59am UTC](https://discourse.julialang.org/t/why-is-there-memory-allocation-and-time-difference-in-views-and-view/58149/7 "2021-03-29T07:59:26Z")

</div>

> [@Shuhua](#):
>
> What is the recommended way to achieve the above goal, i.e., broadcasting over multiple columns of a matrix?

It depends on the specific requirements but this doesn’t allocate at all (either on 1.5 or 1.6):

```julia
julia> @btime y .= (@views X[:,3] .+ X[:,4] .- X[:,5]) setup=(X = randn(1000, 5); y = rand(1000));
  182.881 ns (0 allocations: 0 bytes)

```

---

<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:** [March 29, 2021, 8:00am UTC](https://discourse.julialang.org/t/why-is-there-memory-allocation-and-time-difference-in-views-and-view/58149/8 "2021-03-29T08:00:35Z")

</div>

You weren’t broadcasting `f`, so it was allocating a result that you then used a broadcast to copy into `y`.

---

<div class="post-metadata">

**Author:** ![carstenbauer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/carstenbauer/32/4981_2.png) [@carstenbauer](https://discourse.julialang.org/u/carstenbauer)\
**Post date:** [March 29, 2021, 8:04am UTC](https://discourse.julialang.org/t/why-is-there-memory-allocation-and-time-difference-in-views-and-view/58149/9 "2021-03-29T08:04:35Z")

</div>

Implementing @Elrod’s comment:

Julia 1.6:

```julia
julia> @btime y .= f.((view(X, :, j) for j = 3:5)...) setup=(X = randn(1000, 5); y = rand(1000););
  133.359 ns (0 allocations: 0 bytes)

julia> @btime y .= @views(f.((X[:,j] for j = 3:5)...)) setup=(X = randn(1000, 5); y = rand(1000););
  139.092 ns (0 allocations: 0 bytes)

```

Julia 1.5:

```julia
julia> @btime y .= f.((view(X, :, j) for j = 3:5)...) setup=(X = randn(1000, 5); y = rand(1000););
  711.807 ns (9 allocations: 624 bytes)

julia> @btime y .= @views(f.((X[:,j] for j = 3:5)...)) setup=(X = randn(1000, 5); y = rand(1000););
  729.203 ns (9 allocations: 624 bytes)

```

---

<div class="post-metadata">

**Author:** ![Shuhua](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/shuhua/32/27618_2.png) [@Shuhua](https://discourse.julialang.org/u/Shuhua)\
**Post date:** [March 29, 2021, 8:07am UTC](https://discourse.julialang.org/t/why-is-there-memory-allocation-and-time-difference-in-views-and-view/58149/10 "2021-03-29T08:07:36Z")

</div>

> [@Elrod](#):
>
> You weren’t broadcasting `f` ,

Thanks. A stupid mistake. 😂
