# Slower with threads

**URL:** <https://discourse.julialang.org/t/slower-with-threads/84600>\
**Category:** Performance\
**Tags:** question\
**Created:** [July 21, 2022, 6:49pm UTC](https://discourse.julialang.org/t/slower-with-threads/84600 "2022-07-21T18:49:00Z")\
**Posts on this page:** 7\
**Page:** 2

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)\
**Post date:** [August 5, 2022, 6:02pm UTC](https://discourse.julialang.org/t/slower-with-threads/84600/22 "2022-08-05T18:02:01Z")

</div>

1. You want static arrays wherever you create lots of them in a loop. They won’t incur allocations because their size is known so they’re put on the stack.
2. You can’t modify static arrays, but usually you can store a completely new static array where some values are different than in the previous version, and this is usually fast because, again, no allocation is needed. The compiler is pretty smart about making such things fast. You could look at [GitHub - JuliaObjects/Accessors.jl: Update immutable data](https://github.com/JuliaObjects/Accessors.jl) for example which helps with that.
3. Sparse arrays are something very different. There the optimization is that most elements are zero, so only the non-zero elements are saved with their positions in the array.
4. MMatrix is slower than SMatrix, the mutability prohibits some performance optimizations.

---

<div class="post-metadata">

**Author:** ![marllos](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marllos/32/205917_2.png) [@marllos](https://discourse.julialang.org/u/marllos)\
**Post date:** [August 6, 2022, 12:50am UTC](https://discourse.julialang.org/t/slower-with-threads/84600/23 "2022-08-06T00:50:49Z")

</div>

When I switch to the main job, the optimization stops working! I think my optimization is not optimizing!

---

<div class="post-metadata">

**Author:** ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)\
**Post date:** [August 6, 2022, 2:12am UTC](https://discourse.julialang.org/t/slower-with-threads/84600/24 "2022-08-06T02:12:44Z")

</div>

What you want to do is avoid creating new arrays, allocating memory, on the heap. If you do need to allocate memory, you should see if you can reuse them. This is what the bang functions are for such as [`mul!`](https://docs.julialang.org/en/v1/stdlib/LinearAlgebra/#LinearAlgebra.mul!). Another method is to use broadcast assignment `.=`.

```julia
julia> @allocated A = rand(1:10, 1024, 1024) # Allocates 8 MiB
8388656

julia> @allocated B = rand(1:10, 1024, 1024) # Allocates 8 MiB
8388656

julia> @allocated C = zeros(1024, 1024) # Allocates 8 MiB
8388656

julia> @allocated A .+ B # Allocates 8 MiB to store result
8388720

julia> @allocated C .= A .+ B # Allocates only 64 bytes, avoids 8 MiB allocation
64

julia> using LinearAlgebra

julia> @allocated A * B # allocations due to compilation
115689839

julia> @allocated A * B # > 8 MiB allocated to store result
8420144

julia> @allocated mul!(C, A, B) # allocation due to compilation
123465049

julia> @allocated mul!(C, A, B) # ~31 KiB needed for multiplication, avoid allocating 8 MiB
31488

julia> @allocated C .= A .* B # elementwise multiplication avoids allocating 8 MiB
64

```

StaticArrays.jl uses an optimization for small amounts of memory. The larger strategy to control memory allocation tightly.

---

<div class="post-metadata">

**Author:** ![marllos](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marllos/32/205917_2.png) [@marllos](https://discourse.julialang.org/u/marllos)\
**Post date:** [August 6, 2022, 2:54am UTC](https://discourse.julialang.org/t/slower-with-threads/84600/25 "2022-08-06T02:54:39Z")

</div>

@allocated A = rand(1:10, 1024, 1024) is different from A = rand(1:10, 1024, 1024)?

---

<div class="post-metadata">

**Author:** ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)\
**Post date:** [August 6, 2022, 6:59am UTC](https://discourse.julialang.org/t/slower-with-threads/84600/27 "2022-08-06T06:59:00Z")

</div>

```julia
help?> @allocated
  @allocated

  A macro to evaluate an expression, discarding the resulting value, instead
  returning the total number of bytes allocated during evaluation of the
  expression.

  See also @time, @timev, @timed, and @elapsed.

  julia> @allocated rand(10^6)
  8000080

```

> [@marllos](#):
>
> @allocated A = rand(1:10, 1024, 1024) is different from A = rand(1:10, 1024, 1024)?

No. I’m just measuring allocations

---

<div class="post-metadata">

**Author:** ![marllos](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marllos/32/205917_2.png) [@marllos](https://discourse.julialang.org/u/marllos)\
**Post date:** [August 6, 2022, 4:36pm UTC](https://discourse.julialang.org/t/slower-with-threads/84600/28 "2022-08-06T16:36:50Z")

</div>

Got it. I measured, each thread should allocate around 50 KiB. I love learning Julia, but for now I’ll have to program the hard way: just writing physics equations, until I learn more. But I will use C .= A .+ B, in everything possible. Thanks mkitti.

---

<div class="post-metadata">

**Author:** ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)\
**Post date:** [August 6, 2022, 5:46pm UTC](https://discourse.julialang.org/t/slower-with-threads/84600/29 "2022-08-06T17:46:22Z")

</div>

Note that in Julia 1.8 we now have an allocation profiler:

[![](https://global.discourse-cdn.com/julialang/original/3X/3/2/32354c3b0b6d88ca0cb6da2aa885151d8cc8ea74.jpeg "Hunting down allocations with Julia 1.8's Allocation Profiler | Nathan Daly, Pete Vilter") ](https://www.youtube.com/watch?v=BFvpwC8hEWQ)

[Previous page](https://discourse.julialang.org/t/slower-with-threads/84600.md?page=1)
