How simple get vector from ranges?

The surprising results above are because length is not defined for the Flatten object returned by flatten, which means that the size of the result cannot be determined in advance. If I define:

Base.length(fl::Base.Iterators.Flatten{<:AbstractVector{<:UnitRange}}) = sum(length, fl.it)
Base.iteratorsize(::Base.Iterators.Flatten{<:AbstractVector{<:UnitRange}}) = Base.HasLength()

then the benchmark results for the flatten approach become

BenchmarkTools.Trial: 
  memory estimate:  61.00 MiB
  allocs estimate:  5
  --------------
  minimum time:     21.147 ms (1.61% GC)
  median time:      27.357 ms (20.71% GC)
  mean time:        28.169 ms (22.88% GC)
  maximum time:     90.278 ms (76.97% GC)
  --------------
  samples:          178
  evals/sample:     1

Maybe a more general version of the methods above could make it into Base? We’re getting a lot of mileage out of this simple question.

(As an aside, how awesome is it that you can just tinker like this in Julia!)

Edit: Julia issue: https://github.com/JuliaLang/julia/issues/23431.

3 Likes