editor: Optimize selection overlap checking (#41281)
Xiaobo Liu
created 6 days ago
Replace the binary search approach with a more efficient partition_point
method for checking selection overlaps. This eliminates the need to
collect and sort selection ranges separately, reducing memory allocation
and improving performance when handling multiple selections.
Release Notes:
- N/A
Signed-off-by: Xiaobo Liu <cppcoffee@gmail.com>
Change summary
crates/editor/src/editor.rs | 21 +++++----------------
1 file changed, 5 insertions(+), 16 deletions(-)
Detailed changes
@@ -14335,10 +14335,6 @@ impl Editor {
let last_selection = selections.iter().max_by_key(|s| s.id).unwrap();
let mut next_selected_range = None;
- // Collect and sort selection ranges for efficient overlap checking
- let mut selection_ranges: Vec<_> = selections.iter().map(|s| s.range()).collect();
- selection_ranges.sort_by_key(|r| r.start);
-
let bytes_after_last_selection =
buffer.bytes_in_range(last_selection.end..buffer.len());
let bytes_before_first_selection = buffer.bytes_in_range(0..first_selection.start);
@@ -14360,18 +14356,11 @@ impl Editor {
|| (!buffer.is_inside_word(offset_range.start, None)
&& !buffer.is_inside_word(offset_range.end, None))
{
- // Use binary search to check for overlap (O(log n))
- let overlaps = selection_ranges
- .binary_search_by(|range| {
- if range.end <= offset_range.start {
- std::cmp::Ordering::Less
- } else if range.start >= offset_range.end {
- std::cmp::Ordering::Greater
- } else {
- std::cmp::Ordering::Equal
- }
- })
- .is_ok();
+ let idx = selections
+ .partition_point(|selection| selection.end <= offset_range.start);
+ let overlaps = selections
+ .get(idx)
+ .map_or(false, |selection| selection.start < offset_range.end);
if !overlaps {
next_selected_range = Some(offset_range);