# Is the compiler smart enough to remove this duplicate computation?

**URL:** <https://discourse.julialang.org/t/is-the-compiler-smart-enough-to-remove-this-duplicate-computation/78198>\
**Category:** New to Julia\
**Created:** [March 21, 2022, 7:40am UTC](https://discourse.julialang.org/t/is-the-compiler-smart-enough-to-remove-this-duplicate-computation/78198 "2022-03-21T07:40:33Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![fredrikpaues](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fredrikpaues/32/34080_2.png) [@fredrikpaues](https://discourse.julialang.org/u/fredrikpaues)\
**Post date:** [March 21, 2022, 7:40am UTC](https://discourse.julialang.org/t/is-the-compiler-smart-enough-to-remove-this-duplicate-computation/78198/1 "2022-03-21T07:40:33Z")

</div>

Is the compiler smart enough that it doesn’t compute `diff(w; dims=3)` in the following snippet twice?

```julia
w = rand(2, 3, 4)
@assert(
    all((diff(w; dims=3) .> 0) .| isnan.(diff(w; dims=3))),
    "Something's amiss."
)

```

If it isn’t, then I would rewrite as

```julia
w = rand(2, 3, 4)
f(x) = x > 0 | isnan(x)
@assert(
    all(f.(diff(w; dims=3))),
    "Something's amiss."
)

```

---

<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:** [March 21, 2022, 8:38am UTC](https://discourse.julialang.org/t/is-the-compiler-smart-enough-to-remove-this-duplicate-computation/78198/2 "2022-03-21T08:38:02Z")

</div>

I don’t think it will, since there’s no guarantee that `diff` doesn’t modify `w`. Also, an array could be modified from some other thread. The output of `@code_llvm` and `@code_native` are much too long for me to be able to parse.

You should avoid this pattern in most cases:

```julia
all(f.(diff(w; dims=3)))

```

and instead do

```julia
all(f, diff(w; dims=3))

```

The first creates an unnecessary array allocation, and also calculates `f` for all inputs, even when it could bail out early.

I would just write:

```julia
function bar(w)
    @assert all(x->(x>0 | isnan(x)), diff(w; dims=3)) "Something's amiss."
end

```

BTW, you should be aware of when to use `@assert` (from the docstring):

```julia
 │ Warning
 │
 │ An assert might be disabled at various optimization levels. Assert should therefore only be used as a debugging tool and not used for authentication verification
 │ (e.g., verifying passwords), nor should side effects needed for the function to work correctly be used inside of asserts.

```

Unless you are aware of this already, it’s likely that you should throw an error instead.

---

<div class="post-metadata">

**Author:** ![fredrikpaues](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fredrikpaues/32/34080_2.png) [@fredrikpaues](https://discourse.julialang.org/u/fredrikpaues)\
**Post date:** [March 21, 2022, 8:41am UTC](https://discourse.julialang.org/t/is-the-compiler-smart-enough-to-remove-this-duplicate-computation/78198/3 "2022-03-21T08:41:37Z")

</div>

Thank you! Stellar help, as always 🙂

---

<div class="post-metadata">

**Author:** ![rfourquet](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rfourquet/32/3610_2.png) [@rfourquet](https://discourse.julialang.org/u/rfourquet)\
**Post date:** [March 21, 2022, 8:48am UTC](https://discourse.julialang.org/t/is-the-compiler-smart-enough-to-remove-this-duplicate-computation/78198/4 "2022-03-21T08:48:49Z")

</div>

I would just like to add to the excellent previous answer that that solution is not only more efficient, but easier to read: you don’t have to visually parse twice the same blob (even when they look similar at first sight, developers will expect that they differ as otherwise they would have been factored out, so extra time is spent tracking the tiniest possible detail in which they could be different).

---

<div class="post-metadata">

**Author:** ![goerch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goerch/32/29122_2.png) [@goerch](https://discourse.julialang.org/u/goerch)\
**Post date:** [March 21, 2022, 9:04am UTC](https://discourse.julialang.org/t/is-the-compiler-smart-enough-to-remove-this-duplicate-computation/78198/5 "2022-03-21T09:04:26Z")

</div>

> [@fredrikpaues](#):
>
> Is the compiler smart enough?

I would have thought no, too. But I like to experiment and have

```julia
using BenchmarkTools
using Random

test1(w) =
    all((diff(w; dims=3) .> 0) .| isnan.(diff(w; dims=3)))

test2(w) =
    all(x > 0 || isnan(x) for x in diff(w; dims=3))

test3(w) =
    all(x -> x > 0 || isnan(x), diff(w; dims=3))

Random.seed!(42)
w = rand(2, 3, 4)
r1 = test1(w) 
r2 = test2(w)
@assert r2 == r1
r3 = test3(w)
@assert r3 == r2

@btime test1(w) setup = (Random.seed!(42); w = rand(2, 3, 4))
@btime test2(w) setup = (Random.seed!(42); w = rand(2, 3, 4))
@btime test3(w) setup = (Random.seed!(42); w = rand(2, 3, 4))

```

yielding

```julia
  382.178 ns (4 allocations: 528 bytes) # all(f.(xs))
  126.239 ns (1 allocation: 208 bytes) # all(for x in xs)
  125.670 ns (1 allocation: 208 bytes) # all(f, xs)

```

---

<div class="post-metadata">

**Author:** ![fredrikpaues](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fredrikpaues/32/34080_2.png) [@fredrikpaues](https://discourse.julialang.org/u/fredrikpaues)\
**Post date:** [March 21, 2022, 10:07am UTC](https://discourse.julialang.org/t/is-the-compiler-smart-enough-to-remove-this-duplicate-computation/78198/6 "2022-03-21T10:07:27Z")

</div>

And from this we conclude that it is in fact not smart enough as my original snippet takes more than twice as long and has four times as many allocations…?

---

<div class="post-metadata">

**Author:** ![goerch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goerch/32/29122_2.png) [@goerch](https://discourse.julialang.org/u/goerch)\
**Post date:** [March 21, 2022, 10:15am UTC](https://discourse.julialang.org/t/is-the-compiler-smart-enough-to-remove-this-duplicate-computation/78198/7 "2022-03-21T10:15:09Z")

</div>

> [@DNF](#):
>
> I don’t think it will, since there’s no guarantee that `diff` doesn’t modify `w`

> [@fredrikpaues](#):
>
> And from this we conclude

Yes, currently. But I noticed one interesting development in the [compiler](https://github.com/JuliaLang/julia/commit/f09099206c7d11ffbe25e3416d504dcbdd3de7ec) which could change this behavior in the future AFAIU…

---

<div class="post-metadata">

**Author:** ![goerch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goerch/32/29122_2.png) [@goerch](https://discourse.julialang.org/u/goerch)\
**Post date:** [March 21, 2022, 12:31pm UTC](https://discourse.julialang.org/t/is-the-compiler-smart-enough-to-remove-this-duplicate-computation/78198/8 "2022-03-21T12:31:19Z")

</div>

Edit: deleted due to testing mistake…
