Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

special case flatten of AbstractArray #29769

Closed
wants to merge 1 commit into from

Conversation

chethega
Copy link
Contributor

Adresses #29762.

Idea is that we can keep the state bitstype if the outer iterator is stateless.

Well, AbstractArray is definitely stateless, so it is OK if we access the same element (which is an iterator) multiple times instead of saving it in the state for reuse. Is it guaranteed that A::AbstractArray can be iterated over as firstindex(A), firstindex(A)+1, ... ,lastindex(A)?

The problem with eachindex is that I currently see no way to generically and type-stably access the first element. I am very open for suggestions on how to use the iterator interface for the outer array.

Before:

julia> using BenchmarkTools, Random
julia> Random.seed!(23);
julia> r=[rand(rand(1:10)) for i=1:1000];
julia> @btime collect($(Iterators.flatten(r)));
  149.063 μs (11109 allocations: 475.33 KiB)

After:

julia> using BenchmarkTools, Random
julia> Random.seed!(23);
julia> r=[rand(rand(1:10)) for i=1:1000];
julia> @btime collect($(Iterators.flatten(r)));
  78.652 μs (13 allocations: 128.58 KiB)

@chethega
Copy link
Contributor Author

The speedup from skipping the allocs is pretty modest (2x) for the extra complexity, because push! is so slow.

Not sure whether this is worthwhile, because there are cases where this will probably be a net loser (array types that have slow linear access).

We could of course try to accelerate Flatten{A{B}} where {A<: AbstractArray, B<:AbstractArray}, because this has a length. But we have nowhere to store the length, and computing it is expensive; adding a maybe-length field to Flatten is very breaking, so probably out of discussion.

@mschauer
Copy link
Contributor

Needs test, I think collect(flatten(Diagonal(1:10))) did fail when I tried it on the REPL.

@chethega
Copy link
Contributor Author

Your solution in #29786 is better anyway, no need to debug this one.

@chethega chethega closed this Oct 24, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants