Skip to content

Commit 561e5c8

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) ``` (cherry picked from commit 6440292)
1 parent d6fca15 commit 561e5c8

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
@@ -693,6 +693,8 @@ using .IteratorsMD
693693
end
694694
@inline checkindex(::Type{Bool}, inds::Tuple, I::CartesianIndex) =
695695
checkbounds_indices(Bool, inds, I.I)
696+
@inline checkindex(::Type{Bool}, inds::Tuple, i::AbstractRange{<:CartesianIndex}) =
697+
isempty(i) | (checkindex(Bool, inds, first(i)) & checkindex(Bool, inds, last(i)))
696698

697699
# Indexing into Array with mixtures of Integers and CartesianIndices is
698700
# 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
@@ -1312,4 +1312,9 @@ end
13121312
end
13131313
end
13141314

1315+
@testset "bounds-check with CartesianIndex ranges" begin
1316+
D = Diagonal(1:typemax(Int))
1317+
@test checkbounds(Bool, D, diagind(D, IndexCartesian()))
1318+
end
1319+
13151320
end # module TestDiagonal

0 commit comments

Comments
 (0)