Try zip. If you see a performance hit there too, it would be worth reporting 
(as long as you're testing julia-0.5).

--Tim

On Thursday, March 31, 2016 01:44:17 AM jw3126 wrote:
> Is it possible to chain iterators in julia efficiently? By chaining I mean
> the following. I have a tuple of iterators and I would like to have a
> function "chain" such that
> 
> for itr in iters, i in itr
>     ...
> end
> 
> is equivalent to
> 
> for i in chain(iters)
>    ...
> end
> 
> I found such a function in the Iterators package, however it is not type
> stable and hence dog slow. So I tried to cook up a fast version as follows:
> 
> immutable FastChain{n,T}
>     xss::NTuple{n, T}
> end
> 
> import Base.start
> import Base.next
> import Base.done
> 
> start(it::FastChain) = 1, start(it.xss[1])
> 
> function next{n, T}(it::FastChain{n,T}, state)
>     i, xs_state = state
>     v, xs_state = next(it.xss[i], xs_state)
> 
>     if done(it.xss[i], xs_state)
>         i += 1
>         if i <= n
>             xs_state = start(it.xss[i])
>         end
>     end
>     return v, (i, xs_state)
> end
> 
> done{n,T}(it::FastChain{n,T}, state) = state[1] > n
> 
> While this is indeed type stable and faster then Iterators.chain, it is
> still much slower then the manual version:
> 
> function perf_chain(ch)
>     res = 0
>     for i in ch
>         res += 1
>     end
>     res
> end
> 
> function perf_manual(iters)
>     res = 0
>     for itr in iters, i in itr
>         res += 1
>     end
>     res
> end
> 
> importall Base.Cartesian
> typealias Ci CartesianIndex
> typealias Cr CartesianRange
> 
> # create some iterators e.g. cartesian ranges with 2_000_000 elements
> iter1 = Cr(Ci((2, 3)), Ci((1000, 2000)))
> iter2 = Cr(Ci((2, 3)), Ci((2000, 1000)))
> iters = (iter1, iter2)
> ch = FastChain(iters)
> 
> @assert perf_chain(ch) == perf_manual(iters)
> 
> @time perf_chain(ch)  # 0.035134 seconds (5 allocations: 176 bytes)
> @time perf_manual(iters)  # 0.002136 seconds (5 allocations: 176 bytes)
> 
> I do not understand where this huge performance gap comes from? Any ideas
> for speedup?
> 
> Also I would love to chain iterators which yield the same type of elements,
> but have different state type. Is there a way to achieve this efficiently?
> What worries me is that I don't see how to make the `next` function type
> stable in this case.

Reply via email to