# Avoiding allocations in a map over a tuple

**URL:** https://discourse.julialang.org/t/avoiding-allocations-in-a-map-over-a-tuple/105734
**Category:** General Usage
**Tags:** tuple, memory-allocation
**Created:** [November 2, 2023, 10:30pm UTC](https://discourse.julialang.org/t/avoiding-allocations-in-a-map-over-a-tuple/105734 "2023-11-02T22:30:34Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![CameronBieganek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cameronbieganek/32/6915_2.png) [@CameronBieganek](https://discourse.julialang.org/u/CameronBieganek)
#### Post date: [November 2, 2023, 10:30pm UTC](https://discourse.julialang.org/t/avoiding-allocations-in-a-map-over-a-tuple/105734/1 "2023-11-02T22:30:34Z")

</div>

Is there a way to avoid allocations in this function without using a generated function?

```julia
function foo(t::Tuple)
    map(t) do x
        isodd(x) ? 1 : 1.0
    end
end

```

```julia
julia> using BenchmarkTools

julia> t = (1, 2, 3, 4, 5, 6);

julia> @btime foo($t);
  142.019 ns (4 allocations: 112 bytes)

```

---

<div class="post-metadata">

### Author: ![regan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/regan/32/202923_2.png) [@regan](https://discourse.julialang.org/u/regan)
#### Post date: [November 2, 2023, 10:47pm UTC](https://discourse.julialang.org/t/avoiding-allocations-in-a-map-over-a-tuple/105734/2 "2023-11-02T22:47:39Z")

</div>

My guess is that because `foo` is not type-stable, `julia` has to do some allocating.

In `foo`, the type of the output tuple depends on the _values_ of the input tuple (the elements of the tuple being even or odd), rather than the _type_ of the input tuple.

I’ve demonstrated this by writing `bar`–a similiar looking function that is type-stable–that when run, exhibits a performance gain with no allocating.

```julia
julia> using BenchmarkTools

julia> t = (1, 2, 3, 4, 5, 6);

julia> function foo(t::Tuple)
           map(t) do x
               isodd(x) ? 1 : 1.0
           end
       end

julia> @btime foo($t);
  109.042 ns (4 allocations: 112 bytes)

julia> function bar(t::Tuple)
           map(t) do x
               isodd(x) ? 2.0 : 1.0
           end
       end

julia> @btime bar($t);
  7.300 ns (0 allocations: 0 bytes)

```

---

<div class="post-metadata">

### Author: ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)
#### Post date: [November 2, 2023, 10:51pm UTC](https://discourse.julialang.org/t/avoiding-allocations-in-a-map-over-a-tuple/105734/3 "2023-11-02T22:51:32Z")

</div>

One allocation when written as `ifelse`:

```julia
julia> @btime @. ifelse(isodd($t), 1, 1.0)
  90.356 ns (1 allocation: 64 bytes)
(1, 1.0, 1, 1.0, 1, 1.0)

```

---

<div class="post-metadata">

### Author: ![CameronBieganek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cameronbieganek/32/6915_2.png) [@CameronBieganek](https://discourse.julialang.org/u/CameronBieganek)
#### Post date: [November 2, 2023, 11:24pm UTC](https://discourse.julialang.org/t/avoiding-allocations-in-a-map-over-a-tuple/105734/4 "2023-11-02T23:24:55Z")

</div>

> [@regan](#):
>
> My guess is that because `foo` is not type-stable, `julia` has to do some allocating.
> 
> In `foo`, the type of the output tuple depends on the _values_ of the input tuple (the elements of the tuple being even or odd), rather than the _type_ of the input tuple.

Ah, right, thanks. I didn’t think that through very carefully. Here’s another example with no allocations:

```julia
function bar(t::Tuple)
    map(t) do x
        (x isa Int) ? 1 : 1.0
    end
end

```

```julia
julia> t = (2, 2.0, 2, 2.0, 2, 2.0);

julia> @btime bar($t);
  1.432 ns (0 allocations: 0 bytes)

```
