Skip to content

Conversation

@nsajko
Copy link
Member

@nsajko nsajko commented Feb 11, 2026

Ranges have optimized intersect implementations, so it is fastest in general to just rely on isempty ∘ intersect.

This removes the optimization for empty ranges, however that optimization only results in worse code (extra branching) for common cases such as UnitRange{Int}. Removing the optimization for empty ranges should result in a performance regression in special cases like AbstractRange{BigInt}, when the range is empty. But I suppose that is OK.

Ranges have optimized `intersect` implementations, so it is fastest in
general to just rely on `isempty ∘ intersect`.

This removes the optimization for empty ranges, however that
optimization only results in worse code (extra branching) for common
cases such as `UnitRange{Int}`. Removing the optimization for empty
ranges should result in a performance regression in special cases like
`AbstractRange{BigInt}`, when the range is empty. But I suppose that is
OK.
@nsajko nsajko added performance Must go faster collections Data structures holding multiple items, e.g. sets ranges Everything AbstractRange labels Feb 11, 2026
@nsajko
Copy link
Member Author

nsajko commented Feb 11, 2026

Tests fail here:

julia/test/sets.jl

Lines 481 to 518 in d3dc139

# range fast-path
for (truth, a, b) in (
# Integers
(true, 1:10, 11:20), # not overlapping
(false, 1:10, 5:20), # partial overlap
(false, 5:9, 1:10), # complete overlap
# complete overlap, unequal steps
(false, 3:6:60, 9:9:60),
(true, 4:6:60, 9:9:60),
(true, 0:6:12, 9:9:60),
(false, 6:6:18, 9:9:60),
(false, 12:6:18, 9:9:60),
(false, 18:6:18, 9:9:60),
(true, 1:2:3, 2:3:5),
(true, 1:4:5, 2:1:4),
(false, 4:12:124, 1:1:8),
# potential overflow
(false, 0x1:0x3:0x4, 0x4:0x3:0x4),
(true, 0x3:0x3:0x6, 0x4:0x3:0x4),
(false, typemax(Int8):Int8(3):typemax(Int8), typemin(Int8):Int8(3):typemax(Int8)),
# Chars
(true, 'a':'l', 'o':'p'), # not overlapping
(false, 'a':'l', 'h':'p'), # partial overlap
(false, 'a':'l', 'c':'e'), # complete overlap
# Floats
(true, 1.:10., 11.:20.), # not overlapping
(false, 1.:10., 5.:20.), # partial overlap
(false, 5.:9., 1.:10.), # complete overlap
# Inputs that may hang
(false, -6011687643038262928:3545293653953105048, -6446834672754204848:3271267329311042532),
)
@test isdisjoint(a, b) == truth
@test isdisjoint(b, a) == truth
@test isdisjoint(a, reverse(b)) == truth
@test isdisjoint(reverse(a), b) == truth
@test isdisjoint(b, reverse(a)) == truth
@test isdisjoint(reverse(b), a) == truth
end

However the cause, or one of the causes at least, seems to be a pre-existing bug in intersect:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

collections Data structures holding multiple items, e.g. sets performance Must go faster ranges Everything AbstractRange

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant