# How to remove extra allocation when doing point-wise assignment?

**URL:** <https://discourse.julialang.org/t/how-to-remove-extra-allocation-when-doing-point-wise-assignment/14875>\
**Category:** General Usage\
**Tags:** question\
**Created:** [September 12, 2018, 7:31pm UTC](https://discourse.julialang.org/t/how-to-remove-extra-allocation-when-doing-point-wise-assignment/14875 "2018-09-12T19:31:14Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![shipengcheng1230](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/shipengcheng1230/32/4089_2.png) [@shipengcheng1230](https://discourse.julialang.org/u/shipengcheng1230)\
**Post date:** [September 12, 2018, 7:31pm UTC](https://discourse.julialang.org/t/how-to-remove-extra-allocation-when-doing-point-wise-assignment/14875/1 "2018-09-12T19:31:14Z")

</div>

Hello, I found that if exists assignment, the point-wise loop will introduce lots of additional allocation (on Julia 1.0),

```julia
julia> function f1(a, b, c)
           @. t1 = a * b / c
       end
f1 (generic function with 1 method)

julia> function f2(a, b, c)
           for j = 1: size(a, 2), i = 1: size(a, 1)
               t1[i,j] = a[i,j] * b[i,j] / c[i,j]
           end
       end
f2 (generic function with 1 method)

julia> t1, x1, x2, x3 = [rand(10000, 5000) for _ in 1: 4];

julia> f1(x1, x2, x3); f2(x1, x2, x3);

julia> @time f1(x1, x2, x3);
  0.095687 seconds (8 allocations: 256 bytes)

julia> @time f2(x1, x2, x3);
  2.002025 seconds (142.34 M allocations: 2.121 GiB, 3.33% gc time)

```

As in comparison, the point-wise loop beats the broadcast fusion if no assignment:

```julia
julia> function g1(a, b, c)
           @. a * b / c
       end
g1 (generic function with 1 method)

julia> function g2(a, b, c)
           for j = 1: size(a, 2), i = 1: size(a, 1)
               a[i,j] * b[i,j] / c[i,j]
           end
       end
g2 (generic function with 1 method)

julia> g1(x1, x2, x3); g2(x1, x2, x3);

julia> @time g1(x1, x2, x3);
  0.299063 seconds (6 allocations: 381.470 MiB, 9.51% gc time)

julia> @time g2(x1, x2, x3);
  0.033901 seconds (4 allocations: 160 bytes)

```

Is there anything I am doing improperly? I may need the point-wise loop for implementing SharedArray-based parallelism. Thank you!

---

<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:** [September 12, 2018, 7:36pm UTC](https://discourse.julialang.org/t/how-to-remove-extra-allocation-when-doing-point-wise-assignment/14875/2 "2018-09-12T19:36:19Z")

</div>

You should generally avoid modifying a global variable (your `t1`) within a function. Also, it’s better to use [BenchmarkTools.jl](https://github.com/JuliaCI/BenchmarkTools.jl)’s `@btime` to benchmark your functions performance.

---

<div class="post-metadata">

**Author:** ![Seif\_Shebl](https://avatars.discourse-cdn.com/v4/letter/s/eada6e/32.png) [@Seif\_Shebl](https://discourse.julialang.org/u/Seif_Shebl)\
**Post date:** [September 12, 2018, 9:41pm UTC](https://discourse.julialang.org/t/how-to-remove-extra-allocation-when-doing-point-wise-assignment/14875/3 "2018-09-12T21:41:19Z")

</div>

Avoid that global `t1` as pointed out by @carstenbauer, and they are essentially equal:

```julia
using BenchmarkTools

function f1(t1, a, b, c)
  @. t1 = a * b / c
end

function f2(t1, a, b, c)
  for i in eachindex(a)
    t1[i] = a[i]b[i] / c[i]
  end
end

function ff()
  t1, x1, x2, x3 = [rand(10000,5000) for _ in 1:4]
  @btime f1($t1, $x1, $x2, $x3)
  @btime f2($t1, $x1, $x2, $x3)
end

```

And

```julia
ff()

   100.161 ms (0 allocations: 0 bytes)
   100.087 ms (0 allocations: 0 bytes)

```
