# An assert statement makes my code run faster

**URL:** <https://discourse.julialang.org/t/an-assert-statement-makes-my-code-run-faster/25334>\
**Category:** General Usage\
**Tags:** question\
**Created:** [June 15, 2019, 9:39pm UTC](https://discourse.julialang.org/t/an-assert-statement-makes-my-code-run-faster/25334 "2019-06-15T21:39:18Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![s-baumann](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/s-baumann/32/5843_2.png) [@s-baumann](https://discourse.julialang.org/u/s-baumann)\
**Post date:** [June 15, 2019, 9:39pm UTC](https://discourse.julialang.org/t/an-assert-statement-makes-my-code-run-faster/25334/1 "2019-06-15T21:39:18Z")

</div>

For a case below I get a faster result when I include an assert statement in my code. I include the functions with 5 runs of each case (not including the timing for the first compilation run)

```julia
function with_assert(f::Integer)
    total = 0
    for i in 1:f
        @assert total >= 0 "This should not happen"
        total += total >= 0
    end
    return total
end

function with_nothing(f::Integer)
    total = 0
    for i in 1:f
        total += total >= 0
    end
    return total
end

number = 1000000
@time with_assert(number)
# 0.000235 seconds (5 allocations: 176 bytes)
# 0.000234 seconds (5 allocations: 176 bytes)
# 0.000234 seconds (5 allocations: 176 bytes)
# 0.000234 seconds (5 allocations: 176 bytes)
# 0.000484 seconds (5 allocations: 176 bytes)

@time with_nothing(number)
# 0.000722 seconds (5 allocations: 176 bytes)
# 0.000724 seconds (5 allocations: 176 bytes)
# 0.000708 seconds (5 allocations: 176 bytes)
# 0.000735 seconds (5 allocations: 176 bytes)
# 0.000699 seconds (5 allocations: 176 bytes)

```

This is a contrived example but just for interest, is there any reason this could be happening? I would expect that the assert case would be marginally slower but instead it is about 3 times faster.

---

<div class="post-metadata">

**Author:** ![tkoolen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkoolen/32/1603_2.png) [@tkoolen](https://discourse.julialang.org/u/tkoolen)\
**Post date:** [June 15, 2019, 10:57pm UTC](https://discourse.julialang.org/t/an-assert-statement-makes-my-code-run-faster/25334/2 "2019-06-15T22:57:12Z")

</div>

If you look at the native code for `with_assert`, you’ll notice that there aren’t any instructions related to the assertion. The compiler figured out that since the initial value of `total` is 0 and you’re only adding positive things to it (without the possibility of overflow), it can remove the exception throwing code entirely. In fact, the compiler figured out that `total >= 0` is always `true`, so the immediate value 1 is added in every loop cycle.

In generating the code for `with_nothing`, the compiler was not able to figure this last bit out. So by adding the assertion you basically gave the compiler a hint that allowed it to generate more efficient code in this particular case.

Ideally, this shouldn’t be necessary. It might be interesting to investigate why this optimization isn’t happening without the assertion ‘hint’. Even more ideally, the compiler would recognize that both of these are just inefficient ways of writing integer `abs`.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [June 16, 2019, 5:54am UTC](https://discourse.julialang.org/t/an-assert-statement-makes-my-code-run-faster/25334/3 "2019-06-16T05:54:20Z")

</div>

> [@tkoolen](#):
>
> Ideally, this shouldn’t be necessary. It might be interesting to investigate why this optimization isn’t happening without the assertion ‘hint’. Even more ideally, the compiler would recognize that both of these are just inefficient ways of writing integer `abs` .

I am not an expect on compiler technology, and I am always amazed at what LLVM can optimize these days. But I am wondering if it is reasonable to expect the compiler to become an algebra/proof engine and consider mathematically valid transformations it missed as something to improve upon.

My understanding is that each of these would increase compilation time.

For example, in

```julia
function f(a::Integer, b::Integer, c::Integer, n::Integer)
    @assert a > 0 && b > 0 && c > 0
    @assert n > 2
    a^n + b^n == c^n
end

```

can be optimized away ([Wiles 1995](https://www.jstor.org/stable/2118559)). Is it worth it though?

---

<div class="post-metadata">

**Author:** ![tkoolen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkoolen/32/1603_2.png) [@tkoolen](https://discourse.julialang.org/u/tkoolen)\
**Post date:** [June 16, 2019, 8:07am UTC](https://discourse.julialang.org/t/an-assert-statement-makes-my-code-run-faster/25334/4 "2019-06-16T08:07:06Z")

</div>

> [@Tamas\_Papp](#):
>
> I am not an expect on compiler technology

Nor am I (pretty far from it).

> [@Tamas\_Papp](#):
>
> But I am wondering if it is reasonable to expect the compiler to become an algebra/proof engine and consider mathematically valid transformations it missed as something to improve upon.

Yeah, it’s a trade-off of course. But there is precedent for similar transformations. For example with

```julia
function f(n)
    ret = 0
    for i = 1 : n
        ret += i
    end
    return ret
end

```

LLVM essentially replaces the loop with the formula `n * (n + 1) ÷ 2` (runtime is constant). For the Fermat example, it wouldn’t make sense for the compiler to prove it starting from axioms, but someone could go and write an LLVM pass that recognizes this pattern and applies the theorem. However, it’s probably not very likely that this optimization would be applicable often enough to warrant spending time on it.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [June 16, 2019, 10:32am UTC](https://discourse.julialang.org/t/an-assert-statement-makes-my-code-run-faster/25334/5 "2019-06-16T10:32:54Z")

</div>

> [@tkoolen](#):
>
> someone could go and write an LLVM pass that recognizes this pattern and applies the theorem. However, it’s probably not very likely that this optimization would be applicable often enough to warrant spending time on it.

Perhaps I was not clear: what I am concerned about here is the extra compilation time (and, to a certain extend, code complexity in the compiler).

---

<div class="post-metadata">

**Author:** ![tkoolen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkoolen/32/1603_2.png) [@tkoolen](https://discourse.julialang.org/u/tkoolen)\
**Post date:** [June 16, 2019, 1:09pm UTC](https://discourse.julialang.org/t/an-assert-statement-makes-my-code-run-faster/25334/6 "2019-06-16T13:09:07Z")

</div>

No, that was clear to me.
