# Weird performance sensitivity to order of operations in broadcasted expression

**URL:** <https://discourse.julialang.org/t/weird-performance-sensitivity-to-order-of-operations-in-broadcasted-expression/54568>\
**Category:** General Usage\
**Created:** [February 3, 2021, 10:44pm UTC](https://discourse.julialang.org/t/weird-performance-sensitivity-to-order-of-operations-in-broadcasted-expression/54568 "2021-02-03T22:44:27Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![BridgeBot](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bridgebot/32/21491_2.png) [@BridgeBot](https://discourse.julialang.org/u/BridgeBot)\
**Post date:** [February 3, 2021, 10:44pm UTC](https://discourse.julialang.org/t/weird-performance-sensitivity-to-order-of-operations-in-broadcasted-expression/54568/1 "2021-02-03T22:44:27Z")

</div>

I’m seeing a weird performance sensitivity to order of operations.

```julia
foo1(x,y) = @. x*(x + y) + y*y
foo2(x,y) = @. (x + y)*x + y*y

```

For StaticArray inputs, the first function allocates, while the second function does not.

```julia
x = @SVector [1.0]
y = @SVector [2.0]
julia&gt; @btime foo1($x,$y);
  478.870 ns (25 allocations: 480 bytes)
julia&gt; @btime foo2($x,$y);
  2.949 ns (0 allocations: 0 bytes)

```

Any explanation? Is this expected behavior?

I see a difference in the outputs of `@code_typed` (e.g., `foo1` calls `invoke Base.Broadcast.var` and `Core._apply_iterate` ,`foo2` does not) but I’m not sure how to interpret them.

Note that the original poster on Slack cannot see your response here on Discourse. Consider _transcribing the appropriate answer back to Slack_, or pinging the poster here on Discourse so they can _follow this thread_.  
[(Original message :slack:)](https://julialang.slack.com/archives/C6A044SQH/p1612390947027700?thread_ts=1612390947.027700&cid=C6A044SQH) [(More Info)](https://github.com/JuliaCommunity/SlackBridge)

---

<div class="post-metadata">

**Author:** ![jlchan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jlchan/32/10958_2.png) [@jlchan](https://discourse.julialang.org/u/jlchan)\
**Post date:** [February 3, 2021, 10:53pm UTC](https://discourse.julialang.org/t/weird-performance-sensitivity-to-order-of-operations-in-broadcasted-expression/54568/2 "2021-02-03T22:53:28Z")

</div>

From @mbauman on Slack:

> likely hitting some compiler heuristic threshold for Broadcast.flatten, which is how StaticArrays implements broadcasting. […] Broadcast.flatten is an alternative way to implement broadcasting. It creates lots of anonymous functions. If they don’t inline, you’ll see them as `var"5#6"` s and the like [in @code\_typed].

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [February 3, 2021, 11:03pm UTC](https://discourse.julialang.org/t/weird-performance-sensitivity-to-order-of-operations-in-broadcasted-expression/54568/3 "2021-02-03T23:03:21Z")

</div>

That’s not really a _good_ answer. A better answer is that this is a performance bug — likely the same as [#27988](https://github.com/JuliaLang/julia/issues/27988).

---

<div class="post-metadata">

**Author:** ![jlchan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jlchan/32/10958_2.png) [@jlchan](https://discourse.julialang.org/u/jlchan)\
**Post date:** [February 3, 2021, 11:14pm UTC](https://discourse.julialang.org/t/weird-performance-sensitivity-to-order-of-operations-in-broadcasted-expression/54568/4 "2021-02-03T23:14:27Z")

</div>

Another MWE based on SparseArrays. Both `foo1, foo2` seem to allocate extra, though expanding the product out fully avoids this.

```julia
using SparseArrays
x = sparsevec([1.0])
y = sparsevec([2.0])
foo1(x,y) = @. x*(x + y) + y*y
foo2(x,y) = @. (x + y)*x + y*y
foo3(x,y) = @. x*x + x*y + y*yjulia> @btime foo1($x,$y);
1.111 μs (47 allocations: 1.09 KiB)
julia> @btime foo2($x,$y);
1.124 μs (29 allocations: 1.20 KiB)
julia> @btime foo3($x,$y);
124.881 ns (2 allocations: 192 bytes)

```

---

<div class="post-metadata">

**Author:** ![jlchan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jlchan/32/10958_2.png) [@jlchan](https://discourse.julialang.org/u/jlchan)\
**Post date:** [February 3, 2021, 11:33pm UTC](https://discourse.julialang.org/t/weird-performance-sensitivity-to-order-of-operations-in-broadcasted-expression/54568/5 "2021-02-03T23:33:26Z")

</div>

Neat workaround from @marius311

> In more complex cases a workaround for that issue which also works in your case here is just write the broadcast kernel out by hand,

```julia
foo3(x,y) = broadcast(x,y) do x,y
    x*(x + y) + y*y
end

```
