Why does it make allocation when using tuples parameters in closure?

The following code have some allocation:

using BenchmarkTools

function memoize_test(n_outputs)
    function foo_i(i::Int64, u...)
    end
    return [(u...) -> foo_i(i, u...) for i in 1:n_outputs]
end

fun = memoize_test(10)

u_ = rand(28)
@btime $fun[1]($(u_)...)

Result:

1.560 ΞΌs (59 allocations: 1.14 KiB)

Why does it make some allocation?
If you could give me some tips, thank you very much.

It allocates because the length of u isn’t known to the compiler. The following doesn’t, for example:

julia> @btime $fun[1]($(Tuple(u_))...)
  2.946 ns (0 allocations: 0 bytes)
1 Like

Great. Thank you very much.
However, when I use the package TimerOutputs, why does the result show that there are some allocations?

using TimerOutputs
function test_time()
    u = rand(28)
    u_ = Tuple(u)
    fun = memoize_test(10)
    reset_timer!()
    for i = 1:10
        @timeit "fun" fun[1](u_...)
    end
    show(TimerOutputs.get_defaulttimer());
end
test_time()

Result:

 ────────────────────────────────────────────────────────────────────
                            Time                    Allocations
                   ───────────────────────   ────────────────────────
 Tot / % measured:     28.3ΞΌs /  73.1%           12.2KiB /  93.2%

 Section   ncalls     time    %tot     avg     alloc    %tot      avg
 ────────────────────────────────────────────────────────────────────
 fun           10   20.7ΞΌs  100.0%  2.07ΞΌs   11.4KiB  100.0%  1.14KiB
 ────────────────────────────────────────────────────────────────────

Thank you again.

Some allocations would arise from allocating the vector of functions. If the lengths are known to be constant, perhaps you may use Tuples, or StaticArrays