Skip to content

Commit cd8e82b

Browse files
authored
Optimize findblockindex (#235)
This patch rewrites `findblockindex` to compute the block and the index in one step instead of first looking up the block and then looking up the index. This reduces the time for the following `getindex`-benchmark with around 50%, from 185μs to 84μs. ```julia using BlockArrays, BenchmarkTools const D = rand(100, 100); const B = BlockArray(D, [50, 50], [50, 50]) function getindex_bench(A) s = zero(eltype(A)) for j in axes(A, 2), i in axes(A, 1) s += A[i, j] end return s end @Btime getindex_bench(B) ``` In particular this makes `BlockArray` indexing comparable to `SparseMatrixCSC` indexing: the benchmark above, with `S = sparse(D)`, takes 60μs.
1 parent 2e98546 commit cd8e82b

File tree

1 file changed

+7
-2
lines changed

1 file changed

+7
-2
lines changed

src/blockaxis.jl

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,13 @@
1212
@inline getindex(b::LayoutArray{T,1}, K::BlockIndexRange{1}) where {T} = b[block(K)][K.indices...]
1313

1414
function findblockindex(b::AbstractVector, k::Integer)
15-
K = findblock(b, k)
16-
K[searchsortedfirst(b[K], k)] # guaranteed to be in range
15+
@boundscheck k in b || throw(BoundsError())
16+
bl = blocklasts(b)
17+
blockidx = _searchsortedfirst(bl, k)
18+
@assert blockindex != lastindex(bl) + 1 # guaranteed by the @boundscheck above
19+
prevblocklast = blockidx == firstindex(bl) ? first(b)-1 : bl[blockidx-1]
20+
local_index = k - prevblocklast
21+
return BlockIndex(blockidx, local_index)
1722
end
1823

1924
function _BlockedUnitRange end

0 commit comments

Comments
 (0)