# Why Does @btime Show Near-Zero Execution Time Despite Non-Trivial @code\_native and @code\_llvm Output in Julia?

**URL:** <https://discourse.julialang.org/t/why-does-btime-show-near-zero-execution-time-despite-non-trivial-code-native-and-code-llvm-output-in-julia/118838>\
**Category:** New to Julia\
**Tags:** question\
**Created:** [August 31, 2024, 11:51am UTC](https://discourse.julialang.org/t/why-does-btime-show-near-zero-execution-time-despite-non-trivial-code-native-and-code-llvm-output-in-julia/118838 "2024-08-31T11:51:17Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![alex11](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alex11/32/211715_2.png) [@alex11](https://discourse.julialang.org/u/alex11)\
**Post date:** [August 31, 2024, 11:51am UTC](https://discourse.julialang.org/t/why-does-btime-show-near-zero-execution-time-despite-non-trivial-code-native-and-code-llvm-output-in-julia/118838/1 "2024-08-31T11:51:17Z")

</div>

I’m starting Chris Rackauckas’ course on parallel computation in Julia. In the [first section](https://book.sciml.ai/notes/02-Optimizing_Serial_Code/) in order to show the relationship between types and speed he defines two classes `MyComplex` (a struct of two `Float64`s) and `MySlowComplex` (where the two fields have type `Any`). We expect computation with `MyComplex` to be very fast but computation with `MySlowComplex` to be much slower. He defines a simple function `g(x, y)` to illustrate this. Now indeed

```
a = MyComplex(1.0, 1.0)
b = MyComplex(1.0, 1.0)
@btime g(a, b)

```

outputs `12.303 ns (1 allocation: 32 bytes)` and

```
a = MySlowComplex(1.0, 1.0)
b = MySlowComplex(1.0, 1.0)
@btime g(a, b)

```

outputs `61.725 ns (5 allocations: 96 bytes)` as expected. However, both `@btime g(MyComplex(1.0, 1.0), MyComplex(1.0, 1.0))` and `@btime g(MySlowComplex(1.0, 1.0), MySlowComplex(1.0, 1.0))` output more or less the same `0.854 ns (0 allocations: 0 bytes)`. Now I could understand this if the compiler is doing the computation itself and inlining it. But the problem is that `@code_llvm` applied to these two expressions are radically different. So I suppose I’m confused as to what is going on here. I’m very new to Julia and perhaps don’t understand how @code\_llvm works in the REPL and how the Julia compiler work.

---

<div class="post-metadata">

**Author:** ![screw\_dog](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/screw_dog/32/48119_2.png) [@screw\_dog](https://discourse.julialang.org/u/screw_dog)\
**Post date:** [August 31, 2024, 12:29pm UTC](https://discourse.julialang.org/t/why-does-btime-show-near-zero-execution-time-despite-non-trivial-code-native-and-code-llvm-output-in-julia/118838/2 "2024-08-31T12:29:38Z")

</div>

I’m no expert on `@code_llvm` but getting ns timings without allocations generally means that you are getting constant propagation. That is, the compiler can tell that you are calling a method with constant inputs and just precalculates the result.

The usual advice is to interpolate your function arguments like

```julia
a, b = MySlowComplex(1.0, 1.0), MySlowComplex(1.0, 1.0)
@btime g($a, $b)

```

---

<div class="post-metadata">

**Author:** ![alex11](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alex11/32/211715_2.png) [@alex11](https://discourse.julialang.org/u/alex11)\
**Post date:** [August 31, 2024, 12:41pm UTC](https://discourse.julialang.org/t/why-does-btime-show-near-zero-execution-time-despite-non-trivial-code-native-and-code-llvm-output-in-julia/118838/3 "2024-08-31T12:41:38Z")

</div>

Thanks. I suppose the constant propagation is therefore happening as a result of some kind of runtime optimization because there’s no sign of it either in `@code_native g(MySlowComplex(1.0, 1.0), MySlowComplex(1.0, 1.0))`?

---

<div class="post-metadata">

**Author:** ![abraemer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/abraemer/32/51403_2.png) [@abraemer](https://discourse.julialang.org/u/abraemer)\
**Post date:** [August 31, 2024, 8:48pm UTC](https://discourse.julialang.org/t/why-does-btime-show-near-zero-execution-time-despite-non-trivial-code-native-and-code-llvm-output-in-julia/118838/4 "2024-08-31T20:48:34Z")

</div>

I think `@code_native` really gives you the code of the call to `g` without constant propagation because that wouldn’t be useful usually.  
This is also not what BenchmarkTools.jl runs. Effectively, BT wraps your code into a closure and then runs that repeatedly. You can emulate this for `@code_native` by wrapping the call into an anonymous function and calling it immediately:  
`@code_native (()->g(MySlowComplex(1.0, 1.0), MySlowComplex(1.0, 1.0)))()`

---

<div class="post-metadata">

**Author:** ![alfaromartino](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alfaromartino/32/52986_2.png) [@alfaromartino](https://discourse.julialang.org/u/alfaromartino)\
**Post date:** [August 31, 2024, 11:36pm UTC](https://discourse.julialang.org/t/why-does-btime-show-near-zero-execution-time-despite-non-trivial-code-native-and-code-llvm-output-in-julia/118838/5 "2024-08-31T23:36:00Z")

</div>

I don’t know exactly what the function `g` does, but notice that sometimes the computers (not Julia) are smart enough to realize that you’re repeatedly calculating the same operation. Then, it stops calculating it and just return the same result. A sign of this is when you have times lower than 1 ns.

Usually, the way to trick the computer and force to perform the calculation is using `Ref` and interpolating the variable.

Compare the following

```julia
using BenchmarkTools

function foo(b)
    a = 0 
    for i in 1:1_000_000
        a = 1 + 2 * b # same calculation in each iteration
    end

    return a
end

@btime foo(2) # 0.778 ns

```

while

```julia
ref(x) = (Ref(x))[] 

function foo(b)
    a = 0 
    for i in 1:1_000_000
        a = 1 + 2 * b
    end

    return a
end

b = 2 
@btime foo(ref($b)) # 1.740 ns

```

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [September 1, 2024, 12:33pm UTC](https://discourse.julialang.org/t/why-does-btime-show-near-zero-execution-time-despite-non-trivial-code-native-and-code-llvm-output-in-julia/118838/6 "2024-09-01T12:33:25Z")

</div>

(Even in the second case, it looks like LLVM is summing the series analytically for you rather than executing the loop.)
