How to create fixed-length tuple without heap allocation


#1

The following program allocates memory (according to the @time macro) proportionally to n, which suggests that each invocation of tuple creates something on the heap. Note that the program is written so that the length of the tuple is known at compile time, and hence, in principle, it should be possible to allocate the tuple on the stack. Is there a different technique to create a fixed-length tuple without heap allocation? I think I might be able to solve this problem with a generated function, but maybe something simpler is available?

module test_memtup
function sumtup(j, ::Val{N}) where N
    v = tuple(((j + i) for i=1:N)...)
    sm = 0
    for k = 1 : N
        sm += v[k]
    end
    sm
end

function test(n)
    N = 6
    s = 0
    for k = 1 : n
        s += sumtup(k, Val{N}())
    end
    s
end
end

#2

You should use the ntuple function to generate v:

function sumtup(j, ::Val{N}) where N
    v = ntuple(i->j+i,Val{N}())
    sm = 0
    for k = 1 : N
        sm += v[k]
    end
    sm
end

@benchmark sumtup(3,Val{5}())
BenchmarkTools.Trial: 
  memory estimate:  0 bytes
  allocs estimate:  0
  --------------
  minimum time:     2.338 ns (0.00% GC)
  median time:      2.630 ns (0.00% GC)
  mean time:        2.705 ns (0.00% GC)
  maximum time:     67.517 ns (0.00% GC)
  --------------
  samples:          10000
  evals/sample:     1000

#3

Although this would be the simplest:

sumtup(j, N) = sum(ntuple(i->j+i,N))
@benchmark sumtup(3,Val{5}())
BenchmarkTools.Trial: 
  memory estimate:  0 bytes
  allocs estimate:  0
  --------------
  minimum time:     2.630 ns (0.00% GC)
  median time:      2.923 ns (0.00% GC)
  mean time:        2.928 ns (0.00% GC)
  maximum time:     42.673 ns (0.00% GC)
  --------------
  samples:          10000
  evals/sample:     1000