I was trying to replace calls to digits, which allocates, with a custom iterator, but for some reason calling sum
on it is really slow and allocates, despite e.g. calls to collect
being fast:
using BenchmarkTools
struct DigitsIterator
base::Int
n::Int
end
@inline Base.iterate(it::DigitsIterator) = it.n == 0 ? (0,0) : iterate(it,it.n)
@inline Base.iterate(it::DigitsIterator,el) = el == 0 ? nothing : reverse(divrem(el,it.base))
Base.length(it::DigitsIterator) = ndigits(it.n,base=it.base)
Base.eltype(::Type{DigitsIterator}) = Int
@benchmark sum(DigitsIterator(10,x)) setup=x=rand(0:10^10)
returns
BenchmarkTools.Trial:
memory estimate: 304 bytes
allocs estimate: 8
--------------
minimum time: 2.111 μs (0.00% GC)
median time: 2.241 μs (0.00% GC)
mean time: 2.469 μs (5.69% GC)
maximum time: 1.411 ms (99.53% GC)
--------------
samples: 10000
evals/sample: 9
Any idea what could be going on?