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

Julia Version 1.5.3

``````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 @sudete )
3. What is the recommended way to achieve the above goal, i.e., broadcasting over multiple columns of a matrix?

You forgot to interpolate `X` in the first case

1 Like

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

``````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> @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.)

1 Like

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

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

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

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

``````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)
``````

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

3 Likes

Implementing @Elrod’s comment:

Julia 1.6:

``````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> @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)
``````
2 Likes

Thanks. A stupid mistake.