JuliaLang/julia — pull request #3778 by timholy (2013-07-21 15:09:39+00:00)
Title: RFC: merging range indexes for faster subarray linear indexing

I doubt that any sane person will want to review the index gymnastics here, but this provides huge speed improvements for certain types of SubArray operations. It implements a commented TODO (which I deleted a couple of days ago, so I figured I better do it!): using range indexes, when possible, for trailing linear indexing dimensions. It's an optimization that is only applicable under certain conditions, but those conditions arise fairly commonly in practice (e.g., array slices).

Previously:
```
julia> A = reshape(1:1004*1002*5, 1004, 1002, 5);

julia> s = slice(A, 1:1004, 1:1002, 3);

julia> @time v = s[:];
elapsed time: 1.125853572 seconds (223735572 bytes allocated)

julia> @time v = s[:];
elapsed time: 0.830600176 seconds (216159344 bytes allocated)
```
(My commit from earlier this morning made this already ~2.5x faster than it was yesterday.)

With this code:
```
julia> @time v = s[:];
elapsed time: 0.012385493 seconds (8105976 bytes allocated)

julia> @time v = s[:];
elapsed time: 0.009245699 seconds (8049224 bytes allocated)
```
So about a 100-fold speed improvement, not bad, and indeed it's as fast as `A[:,:,3]`.

The algorithmic details are not fun, but comments on the overall architecture and naming might be useful. For instance, there's a fair amount of overlap between these functions; would it be better to merge them and return `1:0` if the indexes are not mergeable? (One downside is that there would be some additional computational burden on cases where merging fails.) Note also that the code returns either a `Range1` or `Range`, and perhaps that's a bad idea? Finally, feel free to suggest any additional tests that I might have missed.