Skip to content

Commit 50e6b6c

Browse files
jishnubKristofferC
authored andcommitted
Fast bounds-check for CartesianIndex ranges (#55596)
`StepRangeLen{<:CartesianIndex}` indices have been supported since v1.11, but bounds-checking for such indices currently falls back to iterating over the entire range. This PR adds a quick `checkindex` for such ranges. The performance improvement as a consequence: ```julia julia> D = Diagonal(1:10_000); julia> @Btime checkbounds($D, diagind($D, IndexCartesian())); 6.697 μs (0 allocations: 0 bytes) # nightly, O(n) 4.044 ns (0 allocations: 0 bytes) # This PR, O(1) ```
1 parent 06f5fb4 commit 50e6b6c

File tree

2 files changed

+7
-0
lines changed

2 files changed

+7
-0
lines changed

base/multidimensional.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -730,6 +730,8 @@ end
730730
end
731731
@inline checkindex(::Type{Bool}, inds::Tuple, I::CartesianIndex) =
732732
checkbounds_indices(Bool, inds, I.I)
733+
@inline checkindex(::Type{Bool}, inds::Tuple, i::AbstractRange{<:CartesianIndex}) =
734+
isempty(i) | (checkindex(Bool, inds, first(i)) & checkindex(Bool, inds, last(i)))
733735

734736
# Indexing into Array with mixtures of Integers and CartesianIndices is
735737
# extremely performance-sensitive. While the abstract fallbacks support this,

stdlib/LinearAlgebra/test/diagonal.jl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1354,4 +1354,9 @@ end
13541354
end
13551355
end
13561356

1357+
@testset "bounds-check with CartesianIndex ranges" begin
1358+
D = Diagonal(1:typemax(Int))
1359+
@test checkbounds(Bool, D, diagind(D, IndexCartesian()))
1360+
end
1361+
13571362
end # module TestDiagonal

0 commit comments

Comments
 (0)