# Using an assignment outside of threaded for loop degraded performance by a huge amount

**URL:** https://discourse.julialang.org/t/using-an-assignment-outside-of-threaded-for-loop-degraded-performance-by-a-huge-amount/105552
**Category:** General Usage
**Tags:** question, multithreading, threads
**Created:** [October 29, 2023, 11:21pm UTC](https://discourse.julialang.org/t/using-an-assignment-outside-of-threaded-for-loop-degraded-performance-by-a-huge-amount/105552 "2023-10-29T23:21:08Z")
**Posts on this page:** 1
**Showing post:** 8

<div class="post-metadata">

### Author: ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)
#### Post date: [October 30, 2023, 1:33pm UTC](https://discourse.julialang.org/t/using-an-assignment-outside-of-threaded-for-loop-degraded-performance-by-a-huge-amount/105552/8 "2023-10-30T13:33:42Z")

</div>

Actually the interpolation works with `@spawn`, not with `@threads`:

```julia
julia> function f1_2(vcs) # very slow
           T = Int
           smap = Dict("a" => [1:500;], "b" => [1:500;])
           @sync for chunk in makechunks(vcs, nthreads())
               @spawn begin
                   c = zero($T)
                   for v in $chunk
                       for s in v
                           for idx in $smap[s]
                               c += one($T)
                           end
                       end
                   end
               end
           end
           return
       end
f1_2 (generic function with 1 method)

julia> @time f1_2(fill(["a","b"], 500))
  0.045161 seconds (538.60 k allocations: 10.318 MiB, 4.56% gc time, 417.59% compilation time)

julia> @time f1_2(fill(["a","b"], 500))
  0.021519 seconds (495.98 k allocations: 7.588 MiB, 8.42% gc time)

```

Which I used as a solution before (see [Type-instability because of @threads boxing variables - #21 by Elrod](https://discourse.julialang.org/t/type-instability-because-of-threads-boxing-variables/78395/21)). It should be equivalent to creating a let block, but that doesn’t seem to be doing the job here:

```julia
julia> function f1_2(vcs) # very slow
           T = Int
           smap = Dict("a" => [1:500;], "b" => [1:500;])
           @threads for chunk in makechunks(vcs, nthreads())
               let T = T, chunk = chunk, smap = smap
                   c = zero(T)
                   for v in chunk
                       for s in v
                           for idx in smap[s]
                               c += one(T)
                           end
                       end
                   end
               end
           end
           return
       end
f1_2 (generic function with 1 method)

julia> @time f1_2(fill(["a","b"], 500))
  0.048589 seconds (508.51 k allocations: 8.427 MiB, 486.98% compilation time)

julia> @time f1_2(fill(["a","b"], 500))
  0.021447 seconds (495.97 k allocations: 7.588 MiB, 12.07% gc time)

```

Probably there is something I’m missing.

---

_[View the full topic](https://discourse.julialang.org/t/using-an-assignment-outside-of-threaded-for-loop-degraded-performance-by-a-huge-amount/105552)._
