# Fastest way to check if condition is true

**URL:** <https://discourse.julialang.org/t/fastest-way-to-check-if-condition-is-true/32057>\
**Category:** General Usage\
**Created:** [December 9, 2019, 5:27pm UTC](https://discourse.julialang.org/t/fastest-way-to-check-if-condition-is-true/32057 "2019-12-09T17:27:54Z")\
**Posts on this page:** 10\
**Page:** 2

<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:** [December 10, 2019, 9:46pm UTC](https://discourse.julialang.org/t/fastest-way-to-check-if-condition-is-true/32057/21 "2019-12-10T21:46:04Z")

</div>

I meant that you should put your code in functions instead of running things in global scope. And an array doesn’t have to be a global variable.

---

<div class="post-metadata">

**Author:** ![Diger](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/diger/32/36786_2.png) [@Diger](https://discourse.julialang.org/u/Diger)\
**Post date:** [December 10, 2019, 10:18pm UTC](https://discourse.julialang.org/t/fastest-way-to-check-if-condition-is-true/32057/22 "2019-12-10T22:18:37Z")

</div>

And why is it not possible to define an array as const? Let’s say I have an array D with some multiple values inside of which I want to consider the Set. I then define  
Ds=unique(D)  
and then loop over every entry in Ds. Since I do not modify Ds it should be constant and I should be able to write  
const Ds=unique(D)  
but this is not possible somehow.

---

<div class="post-metadata">

**Author:** ![pdeffebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pdeffebach/32/10320_2.png) [@pdeffebach](https://discourse.julialang.org/u/pdeffebach)\
**Post date:** [December 10, 2019, 10:28pm UTC](https://discourse.julialang.org/t/fastest-way-to-check-if-condition-is-true/32057/23 "2019-12-10T22:28:38Z")

</div>

Read the error message julia gives you. You can’t change a non-constant variable to a constant variable (otherwise it wouldn’t really be constant).

---

<div class="post-metadata">

**Author:** ![bashonubuntu](https://avatars.discourse-cdn.com/v4/letter/b/f19dbf/32.png) [@bashonubuntu](https://discourse.julialang.org/u/bashonubuntu)\
**Post date:** [December 10, 2019, 10:34pm UTC](https://discourse.julialang.org/t/fastest-way-to-check-if-condition-is-true/32057/24 "2019-12-10T22:34:07Z")

</div>

To add a bit more

```julia
a = 3 

const a = 4

```

is not allowed but

```julia
const b = 3 

b = 4

```

will be allowed (but will show you a warning that you’re changing the value assigned to the constant).

---

<div class="post-metadata">

**Author:** ![Diger](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/diger/32/36786_2.png) [@Diger](https://discourse.julialang.org/u/Diger)\
**Post date:** [December 10, 2019, 10:36pm UTC](https://discourse.julialang.org/t/fastest-way-to-check-if-condition-is-true/32057/25 "2019-12-10T22:36:09Z")

</div>

Sorry I meant these warnings that appear within the second run of the script.

WARNING: redefining constant Ds  
WARNING: redefining constant ind0

Ds and ind0 are arrays that do not really change within the second run. I also prefixed another constant as such  
const N=20  
and there is no warning for N.

---

<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:** [December 10, 2019, 10:49pm UTC](https://discourse.julialang.org/t/fastest-way-to-check-if-condition-is-true/32057/26 "2019-12-10T22:49:26Z")

</div>

It’s not impossible to give general advice, but it is challenging to follow a discussion about code we haven’t seen. Maybe you can create a runnable example?

---

<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:** [December 12, 2019, 12:14pm UTC](https://discourse.julialang.org/t/fastest-way-to-check-if-condition-is-true/32057/27 "2019-12-12T12:14:33Z")

</div>

Hello.  
I have a newby question.  
Why sometimes do you use **p** and sometimes **$p**?

---

<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:** [December 12, 2019, 12:24pm UTC](https://discourse.julialang.org/t/fastest-way-to-check-if-condition-is-true/32057/28 "2019-12-12T12:24:13Z")

</div>

[https://github.com/JuliaCI/BenchmarkTools.jl/blob/master/doc/manual.md#interpolating-values-into-benchmark-expressions](https://github.com/JuliaCI/BenchmarkTools.jl/blob/master/doc/manual.md#interpolating-values-into-benchmark-expressions)

---

<div class="post-metadata">

**Author:** ![Diger](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/diger/32/36786_2.png) [@Diger](https://discourse.julialang.org/u/Diger)\
**Post date:** [December 12, 2019, 12:39pm UTC](https://discourse.julialang.org/t/fastest-way-to-check-if-condition-is-true/32057/29 "2019-12-12T12:39:40Z")

</div>

This is specific to the BenchmarkingTools package. See his reply " Inside a function, not a loop. And this way of using `$` for variable interpolation is specific to the BenchmarkTools package."

---

<div class="post-metadata">

**Author:** ![Elrod](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/elrod/32/22461_2.png) [@Elrod](https://discourse.julialang.org/u/Elrod)\
**Post date:** [December 12, 2019, 8:38pm UTC](https://discourse.julialang.org/t/fastest-way-to-check-if-condition-is-true/32057/30 "2019-12-12T20:38:30Z")

</div>

Regarding `const` and interpolation, I would think about it in terms of type inference.

```julia
julia> foo(a) = a + b
foo (generic function with 1 method)

julia> b = 3
3

julia> foo(2)
5

julia> @code_warntype foo(2)
Variables
  #self#::Core.Compiler.Const(foo, false)
  a::Int64

Body::Any
1 ─ %1 = (a + Main.b)::Any
└── return %1

```

The function `foo` does not know what `b` is, therefore `a + Main.b` can return anything.  
Examples:

```julia
julia> b = 3.0
3.0

julia> foo(2)
5.0

julia> using ForwardDiff

julia> b = ForwardDiff.Dual(3.0, ForwardDiff.Partials((1.0,0.0,0.0,0.0)))
Dual{Nothing}(3.0,1.0,0.0,0.0,0.0)

julia> foo(2)
Dual{Nothing}(5.0,1.0,0.0,0.0,0.0)

julia> struct WeirdBehavior end

julia> Base.:+(a::Int, ::WeirdBehavior) = println("Hello, world! 🌎")

julia> b = WeirdBehavior()
WeirdBehavior()

julia> foo(2)
Hello, world! 🌎

```

Like the `WeirdBehavior` example shows, essentially anything could happen when we call `foo(::Int)`. When we call `foo`, Julia has to figure out which `+` method is actually supposed to get called, and then dynamically dispatch to that correct function.  
If that `+` method is fast – like adding two integers – this dynamic dispatch will be many times slower than the operation itself.

Things get worse when `foo` is complicated. Because Julia cannot know what the return type of `a + Main.b` is, if the function does anything with the answer (eg, multiplying it by 4), we have the same problem all over again: another dynamic dispatch. The `::Any` is infectious, and can spread, killing performance.

Of course, there were no problems with `a` above. That it is a global variable doesn’t matter; we passed it to `foo` as an argument, letting Julia dispatch to a `foo` specialized for `a::Int`; if we replaced `a` with a `Float64`, Julia would again automatically know it is a `Float64`, and we won’t have a problem with `a`.

So how can we fix `b`? That is, how can we make sure Julia knows its type?  
Obviously, making `b` an argument:

```julia
julia> foo(a, b) = a + b
foo (generic function with 2 methods)

julia> @code_warntype foo(2, 3)
Variables
  #self#::Core.Compiler.Const(foo, false)
  a::Int64
  b::Int64

Body::Int64
1 ─ %1 = (a + b)::Int64
└── return %1

julia> @code_warntype foo(2, 3.0)
Variables
  #self#::Core.Compiler.Const(foo, false)
  a::Int64
  b::Float64

Body::Float64
1 ─ %1 = (a + b)::Float64
└── return %1

julia> @code_warntype foo(2.0, 3.0)
Variables
  #self#::Core.Compiler.Const(foo, false)
  a::Float64
  b::Float64

Body::Float64
1 ─ %1 = (a + b)::Float64
└── return %1

julia> @code_warntype foo(2.0, 3)
Variables
  #self#::Core.Compiler.Const(foo, false)
  a::Float64
  b::Int64

Body::Float64
1 ─ %1 = (a + b)::Float64
└── return %1

```

Now, the specific `+` method that needs to be called within `foo` is known. This means that Julia does not need to dispatch on `+` dynamically, and can instead compile each of the `foo`s into very efficient machine code.

Similarly, we could also instead make `b` a `const`:

```julia
julia> const cb = 3
3

julia> foo(a) = a + cb
foo (generic function with 2 methods)

julia> @code_warntype foo(2)
Variables
 #self#::Core.Compiler.Const(foo, false)
 a::Int64

Body::Int64
1 ─ %1 = (a + Main.cb)::Int64
└── return %1

julia> @code_warntype foo(2.0)
Variables
 #self#::Core.Compiler.Const(foo, false)
 a::Float64

Body::Float64
1 ─ %1 = (a + Main.cb)::Float64
└── return %1

```

Because `b` is constant, it cannot suddenly change; we can’t replace it with a `WeirdBehavior` or anything other than another object of the same type:

```julia
julia> cb = WeirdBehavior()
ERROR: invalid redefinition of constant cb
Stacktrace:
 [1] top-level scope at REPL[50]:1

```

Although, replacing it with another object of the same type will cause problems:

```julia
julia> foo(2)
5

julia> cb = 100
WARNING: redefining constant cb
100

julia> foo(2)
5

```

The function `foo` did not get updated, and is using the old value!

Similarly, when you got warnings about updating arrays

```julia
julia> const B = [1, 2]
2-element Array{Int64,1}:
 1
 2

julia> sumB() = sum(B)
sumB (generic function with 1 method)

julia> sumB()
3

julia> B[1] = 100
100

julia> sumB()
102

julia> B = [-10^6, -10^7]
WARNING: redefining constant B
2-element Array{Int64,1}:
  -1000000
 -10000000

julia> sumB()
102

julia> B[1] = 10^9
1000000000

julia> sumB()
102

```

The function `sumB` is still using the old array `B`, and modifying the new one no longer changes the answers we’re getting.

Best not to change a global constant.  
This is all also fairly awkward, which is why it’s normally better to pass things as function arguments, if you can.

What does this all have to do with interpolation?

Our original problem was that the `+` inside `foo` was a dynamic dispatch, because the type of `Main.b` was not known.  
In reality, if we have type stable code (most of the time), we wont have this problem, so we don’t want to benchmark the dynamic dispatches.

However, when we benchmark a function

```julia
@benchmark x + y

```

that is precisely what we’re doing: benchmarking the dynamic dispatch (assuming `x` and `y` aren’t both `const`). The `BenchmarkTools` library however has a hack, letting us use `$` to avoid the dynamic dispatch, and call `+` as though we were calling it inside a type stable function:

```julia
@benchmark $x + $y

```

Which in reality is what we’re interested in the vast majority of the time.

Note that if `x` and `y` are simple objects like numbers, the above will probably report times much less than `ns`, because the optimizer can realize the answer is constant and thus avoid recomputing it, defeating the benchmark. That is another problem which (for now) you can avoid via something like:

```julia
julia> using BenchmarkTools

julia> @benchmark $(Ref(2))[] + $(Ref(3))[]
BenchmarkTools.Trial:
  memory estimate: 0 bytes
  allocs estimate: 0
  --------------
  minimum time: 1.534 ns (0.00% GC)
  median time: 1.538 ns (0.00% GC)
  mean time: 1.609 ns (0.00% GC)
  maximum time: 14.689 ns (0.00% GC)
  --------------
  samples: 10000
  evals/sample: 1000

```

but the smarter the compiler gets, the harder it will be to trick it into doing enough useless work to accurately time how long a computation takes.

[Previous page](https://discourse.julialang.org/t/fastest-way-to-check-if-condition-is-true/32057.md?page=1)
