# Pre-allocating outputs, inplace functions and performance

**URL:** <https://discourse.julialang.org/t/pre-allocating-outputs-inplace-functions-and-performance/34271>\
**Category:** General Usage\
**Created:** [February 6, 2020, 8:31pm UTC](https://discourse.julialang.org/t/pre-allocating-outputs-inplace-functions-and-performance/34271 "2020-02-06T20:31:17Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![cosmia](https://avatars.discourse-cdn.com/v4/letter/c/9de0a6/32.png) [@cosmia](https://discourse.julialang.org/u/cosmia)\
**Post date:** [February 6, 2020, 8:31pm UTC](https://discourse.julialang.org/t/pre-allocating-outputs-inplace-functions-and-performance/34271/1 "2020-02-06T20:31:17Z")

</div>

Hi all, I’m trying to understand the Pre-allocating outputs section in the performance tips of the docs.

I have a code that basically does the following:

```julia
function test(x, a)
    if a == 1
        res = x .^ 2
    else
        res = x .^ 3
    end
    return res
end

ret = ones(10)
x = ones(10) .* 5
a = 1
for k = 1:10
    ret .*= test(x,a)
end

```

Now, abstracting away from global variable issues, I thought that this would be a good example on how to gain some efficiency with pre-allocated outputs, so following the docs, I modified above as:

```julia
function test!(ret, x, a)
    if a == 1
        ret = x .^ 2
    else
        ret = x .^ 3
    end
    nothing
end

ret = Array{Float64}(undef, 10)
x = ones(10) .* 5
a = 1
temp = ones(10)
for k = 1:10
    test!(ret, x,a)
    temp .*= ret
end

```

However, `test!(ret,x,a)` does not change the Array ret, and modifying test! to `return test` and adding `ret = test!(ret, x, a)` would defeat the purpose of pre-allocating the array, right? Finally, even if the above code worked, would it even make a difference, since now I create the temporary array `temp`?

---

<div class="post-metadata">

**Author:** ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)\
**Post date:** [February 6, 2020, 8:35pm UTC](https://discourse.julialang.org/t/pre-allocating-outputs-inplace-functions-and-performance/34271/2 "2020-02-06T20:35:02Z")

</div>

You want to use `ret .= x.^2`. otherwise you won’t be copying into the existing vector, you’ll just be changing what it’s assigned to.

---

<div class="post-metadata">

**Author:** ![tbeason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tbeason/32/15898_2.png) [@tbeason](https://discourse.julialang.org/u/tbeason)\
**Post date:** [February 6, 2020, 8:35pm UTC](https://discourse.julialang.org/t/pre-allocating-outputs-inplace-functions-and-performance/34271/3 "2020-02-06T20:35:52Z")

</div>

You aren’t modifying `ret` in that function. You need to use the inplace equals `.=` or `ret[:] = x.^2`

---

<div class="post-metadata">

**Author:** ![cosmia](https://avatars.discourse-cdn.com/v4/letter/c/9de0a6/32.png) [@cosmia](https://discourse.julialang.org/u/cosmia)\
**Post date:** [February 6, 2020, 8:47pm UTC](https://discourse.julialang.org/t/pre-allocating-outputs-inplace-functions-and-performance/34271/4 "2020-02-06T20:47:08Z")

</div>

gosh, this is embarrassing. thanks a lot for the prompt reply!

---

<div class="post-metadata">

**Author:** ![tbeason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tbeason/32/15898_2.png) [@tbeason](https://discourse.julialang.org/u/tbeason)\
**Post date:** [February 6, 2020, 9:12pm UTC](https://discourse.julialang.org/t/pre-allocating-outputs-inplace-functions-and-performance/34271/5 "2020-02-06T21:12:00Z")

</div>

Dang, missed the solution by seconds! 🐢

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [February 7, 2020, 12:08am UTC](https://discourse.julialang.org/t/pre-allocating-outputs-inplace-functions-and-performance/34271/6 "2020-02-07T00:08:01Z")

</div>

There’s a simpler way here that you can try:

```julia
ret .*= test.(x, a)

```

Then you don’t need the `test!` version, and you can also drop the broadcasting inside `test`. You should check it for performance, though (with BenchmarkTools.jl). Hopefully, constant propagation can eliminate the branch, but I’m not certain.

---

<div class="post-metadata">

**Author:** ![simeonschaub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/simeonschaub/32/216566_2.png) [@simeonschaub](https://discourse.julialang.org/u/simeonschaub)\
**Post date:** [February 7, 2020, 12:26am UTC](https://discourse.julialang.org/t/pre-allocating-outputs-inplace-functions-and-performance/34271/7 "2020-02-07T00:26:05Z")

</div>

Note that `ret[:] = x.^2` will still allocate a separate vector `x.^2`, so this is probably not what the OP is looking for.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [February 7, 2020, 7:55am UTC](https://discourse.julialang.org/t/pre-allocating-outputs-inplace-functions-and-performance/34271/8 "2020-02-07T07:55:34Z")

</div>

> [@cosmia](#):
>
> adding `ret = test!(ret, x, a)` would defeat the purpose of pre-allocating the array, right?

Note that this isn’t right. There is nothing wrong with returning the mutated container, it’s in fact a very common pattern. Writing `ret = test!(ret, x, a)` we reassign `ret` but it will be assigned back to itself without creating any allocations. It’s a bit like writing `ret = ret`.

---

<div class="post-metadata">

**Author:** ![cosmia](https://avatars.discourse-cdn.com/v4/letter/c/9de0a6/32.png) [@cosmia](https://discourse.julialang.org/u/cosmia)\
**Post date:** [February 7, 2020, 5:25pm UTC](https://discourse.julialang.org/t/pre-allocating-outputs-inplace-functions-and-performance/34271/9 "2020-02-07T17:25:11Z")

</div>

> There’s a simpler way here that you can try:
> 
> ```julia
> ret .*= test.(x, a)
> 
> ```
> 
> Then you don’t need the `test!` version, and you can also drop the broadcasting inside `test` . You should check it for performance, though (with BenchmarkTools.jl). Hopefully, constant propagation can eliminate the branch, but I’m not certain.

That is something that I tried doing, but it seems that it would be a little convoluted for my case, since in my actual case, I have a vector of parameters of a smaller size, while `x` is a vector of values, as in:

```julia
function test(a, b, x)
    if a == 1
        ret = x ^ b[1]
    else
        ret = x ^ b[2]
    end
    return ret
end
x = ones(10) .* 5
b = [2, 3]
a = 1
ret = test.(a, b, x) # broadcast error
ret = test.(a, b[1], x) # works fine

```

I could break the function into 4 parameters, but the size of `b` varies slightly depending on the case.

> [@simeonschaub](#):
>
> Note that `ret[:] = x.^2` will still allocate a separate vector `x.^2` , so this is probably not what the OP is looking for.

Yes, I noticed that the number of allocations did not decrease if I used `ret[:]`, thanks!

> [@DNF](#):
>
> Note that this isn’t right. There is nothing wrong with returning the mutated container, it’s in fact a very common pattern. Writing `ret = test!(ret, x, a)` we reassign `ret` but it will be assigned back to itself without creating any allocations. It’s a bit like writing `ret = ret` .

Interesting, thanks for the insight!

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [February 7, 2020, 5:29pm UTC](https://discourse.julialang.org/t/pre-allocating-outputs-inplace-functions-and-performance/34271/10 "2020-02-07T17:29:40Z")

</div>

You can do

```julia
ret = test.(a, Ref(b), x)

```

or

```julia
ret = test.(a, (b,), x)

```

though I believe that `Ref` is slightly preferred.

---

<div class="post-metadata">

**Author:** ![cosmia](https://avatars.discourse-cdn.com/v4/letter/c/9de0a6/32.png) [@cosmia](https://discourse.julialang.org/u/cosmia)\
**Post date:** [February 7, 2020, 5:38pm UTC](https://discourse.julialang.org/t/pre-allocating-outputs-inplace-functions-and-performance/34271/11 "2020-02-07T17:38:10Z")

</div>

This works, thanks a lot! Everyday learning new things.

Interestingly, the number of allocation using your method is almost half of the inplace method, but also about 5% slower.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [February 7, 2020, 5:45pm UTC](https://discourse.julialang.org/t/pre-allocating-outputs-inplace-functions-and-performance/34271/12 "2020-02-07T17:45:40Z")

</div>

How are doing the benchmarking?

---

<div class="post-metadata">

**Author:** ![cosmia](https://avatars.discourse-cdn.com/v4/letter/c/9de0a6/32.png) [@cosmia](https://discourse.julialang.org/u/cosmia)\
**Post date:** [February 7, 2020, 6:00pm UTC](https://discourse.julialang.org/t/pre-allocating-outputs-inplace-functions-and-performance/34271/13 "2020-02-07T18:00:42Z")

</div>

I’m using BenchmarkTools!

---

<div class="post-metadata">

**Author:** ![Juan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juan/32/7657_2.png) [@Juan](https://discourse.julialang.org/u/Juan)\
**Post date:** [February 7, 2020, 10:50pm UTC](https://discourse.julialang.org/t/pre-allocating-outputs-inplace-functions-and-performance/34271/14 "2020-02-07T22:50:51Z")

</div>

Could you explain the reason to use Ref, please?
