From b5705d36ff3724c98cc4247bc323f0a31b2e5fb8 Mon Sep 17 00:00:00 2001 From: Tim Holy Date: Tue, 18 Nov 2014 20:34:20 -0600 Subject: [PATCH] SubArrays: fix first_index bottleneck in construction --- base/subarray.jl | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/base/subarray.jl b/base/subarray.jl index 6084f66c8930c..ea5dfc6fc02fb 100644 --- a/base/subarray.jl +++ b/base/subarray.jl @@ -45,7 +45,11 @@ stagedfunction slice{T,NP}(A::AbstractArray{T,NP}, I::ViewIndex...) dims = :(tuple($(sizeexprs...))) LD = subarray_linearindexing_dim(A, I) strideexpr = stride1expr(A, I, :A, :I, LD) - :(SubArray{$T,$N,$A,$I,$LD}(A, I, $dims, first_index(A, I), $strideexpr)) + exfirst = first_index_expr(:A, :I, length(I)) + quote + $exfirst + SubArray{$T,$N,$A,$I,$LD}(A, I, $dims, f, $strideexpr) + end end # Conventional style (drop trailing singleton dimensions, keep any other singletons) @@ -74,7 +78,11 @@ stagedfunction sub{T,NP}(A::AbstractArray{T,NP}, I::ViewIndex...) It = tuple(Itypes...) LD = subarray_linearindexing_dim(A, I) strideexpr = stride1expr(A, I, :A, :I, LD) - :(SubArray{$T,$N,$A,$It,$LD}(A, $Iext, $dims, first_index(A, I), $strideexpr)) + exfirst = first_index_expr(:A, :I, length(It)) + quote + $exfirst + SubArray{$T,$N,$A,$It,$LD}(A, $Iext, $dims, f, $strideexpr) + end end # Constructing from another SubArray @@ -141,9 +149,11 @@ stagedfunction slice{T,NV,PV,IV,PLD}(V::SubArray{T,NV,PV,IV,PLD}, I::ViewIndex.. It = tuple(Itypes...) LD = max(LD, subarray_linearindexing_dim(PV, It)) strideexpr = stride1expr(PV, It, :(V.parent), :Inew, LD) + exfirst = first_index_expr(:(V.parent), :Inew, length(It)) quote Inew = $Inew - SubArray{$T,$N,$PV,$It,$LD}(V.parent, Inew, $dims, first_index(V.parent, Inew), $strideexpr) + $exfirst + SubArray{$T,$N,$PV,$It,$LD}(V.parent, Inew, $dims, f, $strideexpr) end end @@ -214,10 +224,12 @@ stagedfunction sub{T,NV,PV,IV,PLD}(V::SubArray{T,NV,PV,IV,PLD}, I::ViewIndex...) LD = max(LD, subarray_linearindexing_dim(PV, It)) strideexpr = stride1expr(PV, It, :(V.parent), :Inew, LD) preex = isempty(preexprs) ? nothing : Expr(:block, preexprs...) + exfirst = first_index_expr(:(V.parent), :Inew, length(It)) quote $preex Inew = $Inew - SubArray{$T,$N,$PV,$It,$LD}(V.parent, Inew, $dims, first_index(V.parent, Inew), $strideexpr) + $exfirst + SubArray{$T,$N,$PV,$It,$LD}(V.parent, Inew, $dims, f, $strideexpr) end end @@ -301,6 +313,18 @@ function first_index(P::AbstractArray, indexes::Tuple) f end +function first_index_expr(Asym, Isym::Symbol, n::Int) + ex = :(f = s = 1) + for i = 1:n + ex = quote + $ex + f += (first($Isym[$i])-1)*s + s *= size($Asym, $i) + end + end + ex +end + # Detecting whether one can support fast linear indexing function nextLD(Ilast, I, LD, die_next_vector) isdone = false