# Understanding memory allocations

**URL:** <https://discourse.julialang.org/t/understanding-memory-allocations/46379>\
**Category:** Performance\
**Created:** [September 10, 2020, 1:08pm UTC](https://discourse.julialang.org/t/understanding-memory-allocations/46379 "2020-09-10T13:08:31Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Philippe\_Maincon1](https://avatars.discourse-cdn.com/v4/letter/p/ec9cab/32.png) [@Philippe\_Maincon1](https://discourse.julialang.org/u/Philippe_Maincon1)\
**Post date:** [September 10, 2020, 1:08pm UTC](https://discourse.julialang.org/t/understanding-memory-allocations/46379/1 "2020-09-10T13:08:31Z")

</div>

I want _fast_ code. 🕶 I _will_ get a core meltdown.

I try to understand why some code allocates while other doesn’t. Here is my little benchmark, and I cannot make head or tail of the results.

```julia
b = Complex(1.,2.)

foo(a,b) = a+b
o = foo(1.,2.)
@time o = foo(1.,2.)

0.000000 seconds

o =Complex(imag(b) , real(b) ) 
@time o = Complex(imag(b) , real(b) ) 

0.000004 seconds (3 allocations: 64 bytes)

o = imag(b)
@time o =imag(b)

0.000009 seconds (1 allocation: 16 bytes)

bar(b::Complex) = Complex(imag(b) , real(b) ) 
o = bar(Complex(1.,2.))
@time o = bar(Complex(1.,2.))

0.000000 seconds WHAAAAT !?!

baz(b::Complex) = Complex(1.,2. ) 
o = baz(Complex(1.,2.))
@time o = baz(Complex(1.,2.))

0.000000 seconds

b = Complex(1.,2.)
@time o = Complex(1.,2.)

0.000000 seconds

buz(a,b) = Complex(b,a) 
o = buz(1.,2.)
@time o = buz(1.,2.)

0.000000 seconds  

```

Wow. Any preconception of additivity is hereby shattered!

First question: what is counted here is heap allocations? Then: How can I learn to create operations without allocation?

---

<div class="post-metadata">

**Author:** ![tomerarnon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomerarnon/32/3170_2.png) [@tomerarnon](https://discourse.julialang.org/u/tomerarnon)\
**Post date:** [September 10, 2020, 2:09pm UTC](https://discourse.julialang.org/t/understanding-memory-allocations/46379/2 "2020-09-10T14:09:58Z")

</div>

I wouldn’t trust any benchmark that  
a) is done in the global scope  
b) uses `@time` on a fast function  
c) produces 0 a second output (unless `@code_native` shows it’s a no-op)

Since these are all timing between 1 and a handful of machine instructions though, they should indeed be very fast. None of them allocate as written.

```julia
julia> using BenchmarkTools

julia> let b = Complex(1.0, 2.0)

           foo(a, b) = a+b
           bar(b::Complex) = Complex(imag(b), real(b))

           @btime foo(Ref(1.0)[], Ref(2.0)[])
           @btime Complex(imag($(Ref(b))[]), real($(Ref(b))[]))
           @btime imag($(Ref(b))[])
           @btime bar($(Ref(Complex(1.0, 2.0)))[])
       end
  1.644 ns (0 allocations: 0 bytes)
  1.963 ns (0 allocations: 0 bytes)
  1.643 ns (0 allocations: 0 bytes)
  1.643 ns (0 allocations: 0 bytes)

```

---

<div class="post-metadata">

**Author:** ![Philippe\_Maincon1](https://avatars.discourse-cdn.com/v4/letter/p/ec9cab/32.png) [@Philippe\_Maincon1](https://discourse.julialang.org/u/Philippe_Maincon1)\
**Post date:** [September 10, 2020, 2:13pm UTC](https://discourse.julialang.org/t/understanding-memory-allocations/46379/3 "2020-09-10T14:13:51Z")

</div>

Ah! Many thanks Tom. I was trying to make sense of random measurement errors!

Excellent, now I know how to bench mark my real-world problem. 😀

You call foo and bar using patterns like `Ref(1.0)[]`. Replacing that with `1.0` does not seem to affect the output of your benchmark. What is the idea?

And same question with $b : is this the macro interpolation syntax?

---

<div class="post-metadata">

**Author:** ![tomerarnon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomerarnon/32/3170_2.png) [@tomerarnon](https://discourse.julialang.org/u/tomerarnon)\
**Post date:** [September 10, 2020, 2:23pm UTC](https://discourse.julialang.org/t/understanding-memory-allocations/46379/4 "2020-09-10T14:23:26Z")

</div>

Great!  
I should say that my sub-nanosecond times were _also_ quite suspicious. I went back and fixed where the `Ref`s were and the results make more sense now. The [documentation](https://github.com/JuliaCI/BenchmarkTools.jl) discusses why this happens

---

<div class="post-metadata">

**Author:** ![Philippe\_Maincon1](https://avatars.discourse-cdn.com/v4/letter/p/ec9cab/32.png) [@Philippe\_Maincon1](https://discourse.julialang.org/u/Philippe_Maincon1)\
**Post date:** [September 10, 2020, 2:24pm UTC](https://discourse.julialang.org/t/understanding-memory-allocations/46379/5 "2020-09-10T14:24:57Z")

</div>

Thanks - read the docs… ! 😉 😀

---

<div class="post-metadata">

**Author:** ![rveltz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rveltz/32/2707_2.png) [@rveltz](https://discourse.julialang.org/u/rveltz)\
**Post date:** [September 10, 2020, 4:48pm UTC](https://discourse.julialang.org/t/understanding-memory-allocations/46379/6 "2020-09-10T16:48:31Z")

</div>

why the results looks strange to you?

## first case

everything is plain value, nothing is allocated, except maybe `o`

## second case

allocation of `imag(b), real(b), o` 3allocationd

## 3rd case

allocation of imag(b) one alloc

etc

---

<div class="post-metadata">

**Author:** ![Philippe\_Maincon1](https://avatars.discourse-cdn.com/v4/letter/p/ec9cab/32.png) [@Philippe\_Maincon1](https://discourse.julialang.org/u/Philippe_Maincon1)\
**Post date:** [September 11, 2020, 5:47am UTC](https://discourse.julialang.org/t/understanding-memory-allocations/46379/7 "2020-09-11T05:47:08Z")

</div>

Morning!

Well, consider the call to “bar” which combine some of the operations you mention - and has reportedly zero allocation. But Tom mailed the issue: my measurements where wrong. Carefully using @btime I get results that make much better sense.
