# Tuple indexing taking time?

**URL:** <https://discourse.julialang.org/t/tuple-indexing-taking-time/58309>\
**Category:** Performance\
**Created:** [March 31, 2021, 3:56pm UTC](https://discourse.julialang.org/t/tuple-indexing-taking-time/58309 "2021-03-31T15:56:43Z")\
**Posts on this page:** 6\
**Page:** 2

<div class="post-metadata">

**Author:** ![Skoffer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/skoffer/32/378_2.png) [@Skoffer](https://discourse.julialang.org/u/Skoffer)\
**Post date:** [March 31, 2021, 6:04pm UTC](https://discourse.julialang.org/t/tuple-indexing-taking-time/58309/21 "2021-03-31T18:04:00Z")

</div>

You can try `map` to unroll tuples correctly.

```julia
using BenchmarkTools
f1(x) = x^2
f2(x) = x^3
f3(x) = x^4
f4(x) = x^5
t = (f1, f2, f3, f4)

function g1(t, x)
    res = 0
    for i in 1:length(t)
        res += t[i](x)
    end
    return res
end

g2(t, x) = sum(map(f -> f(x), t))

julia> @btime g1($t, 2)
  190.059 ns (0 allocations: 0 bytes)
60

julia> @btime g2($t, 2)
  8.477 ns (0 allocations: 0 bytes)
60

```

---

<div class="post-metadata">

**Author:** ![markmbaum](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/markmbaum/32/32745_2.png) [@markmbaum](https://discourse.julialang.org/u/markmbaum)\
**Post date:** [March 31, 2021, 6:12pm UTC](https://discourse.julialang.org/t/tuple-indexing-taking-time/58309/22 "2021-03-31T18:12:20Z")

</div>

I see… I will see if that gives the same, or better, improvement. Any simple explanation of why mapping is efficient in this scenario?

---

<div class="post-metadata">

**Author:** ![Skoffer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/skoffer/32/378_2.png) [@Skoffer](https://discourse.julialang.org/u/Skoffer)\
**Post date:** [March 31, 2021, 6:18pm UTC](https://discourse.julialang.org/t/tuple-indexing-taking-time/58309/23 "2021-03-31T18:18:00Z")

</div>

Naively speaking (and it’s really my mental model of how julia operates, it can be far away from reality), when you are going through the loop, compiler is unable to determine which function is going to be run next, so it has to determine it in runtime. Which means, that when you are executing program for each new value of `i` it pauses and tries to determine which function should be executed now. It looks it up with the help of big and complicated dictionary and it takes a lot of time.

On the other hand, when you are applyng `map`, due to the way this function is implemented, compiler is turning it’s call into something like this `(f1(x), f2(x), f3(x), f4(x))`, so it knows at compile time which function is going to be call when and it needs not to make this huge dynamical lookup.

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [March 31, 2021, 6:31pm UTC](https://discourse.julialang.org/t/tuple-indexing-taking-time/58309/24 "2021-03-31T18:31:48Z")

</div>

You can also use recursion to iterate over tuples of varying types without losing type-stability, as discussed here: [Manual dispatch over a constant type set - #4 by rdeits](https://discourse.julialang.org/t/manual-dispatch-over-a-constant-type-set/57811/4)

---

<div class="post-metadata">

**Author:** ![Skoffer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/skoffer/32/378_2.png) [@Skoffer](https://discourse.julialang.org/u/Skoffer)\
**Post date:** [March 31, 2021, 6:37pm UTC](https://discourse.julialang.org/t/tuple-indexing-taking-time/58309/25 "2021-03-31T18:37:43Z")

</div>

Oh, you are right, its rather amazing

```julia
function call_for_each(x::T, t) where T
    isempty(t) && return zero(T)
    return first(t)(x) + call_for_each(x, Base.tail(t))
end

```

```julia
julia> @btime call_for_each(2, $t)
  6.880 ns (0 allocations: 0 bytes)

```

It’s even faster than `map` method.

---

<div class="post-metadata">

**Author:** ![markmbaum](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/markmbaum/32/32745_2.png) [@markmbaum](https://discourse.julialang.org/u/markmbaum)\
**Post date:** [April 1, 2021, 2:51pm UTC](https://discourse.julialang.org/t/tuple-indexing-taking-time/58309/26 "2021-04-01T14:51:00Z")

</div>

Yep, @rdeits that appears to be the best solution so far. Using an organizing type helped and took the whole calculation down to 172 ms, but it’s clunky. The tuple recursion is pretty simple, takes it down to 140 ms, and the new profile is looking great.

 ![Untitled](https://global.discourse-cdn.com/julialang/original/3X/b/4/b4b4092cdb87d92f529e8e4405eb5d0c2d925cbb.png)

[Previous page](https://discourse.julialang.org/t/tuple-indexing-taking-time/58309.md?page=1)
