Selection: a hover checks the bounds memo once, not once per object

Hovering looks up the bounds of every selected object, and each lookup
went through the memo key check, which compares the whole selection. That
made a hover quadratic in the selection: 1.5 s at 50,000 selected paths.

The walk now checks the key once and shares it across its lookups.

Part of #1280.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
FredApps
2026-11-06 01:07:34 +07:00
committed by bflatastic
co-authored by Claude Opus 5.5
parent a15d213eb6
commit 64f7b49dea
2 changed files with 66 additions and 10 deletions
+25
View File
@@ -878,6 +878,31 @@ fn a_handle_drag_keeps_the_opposite_edge_of_the_offset_shape() {
}
}
#[test]
fn a_hover_checks_the_memo_as_often_however_many_objects_are_selected() {
let checks = |objects: u32| {
let mut s = session();
for i in 0..objects {
rect(&mut s, f64::from(i), 1.0, 0.0);
}
run(&mut s, "select.all", json!({}));
let v = ViewInfo::default();
s.select_tool("selection", v).unwrap();
// Off the art, so the hover walks every selected object and finds no anchor or center.
let hover = |s: &mut Session| {
s.pointer(&PointerEvent::new(PointerKind::Move, 350.0, 350.0), v).unwrap();
s.cursor(Point::new(350.0, 350.0), Mods::default(), v)
};
hover(&mut s);
let before = s.preview_memo.checks();
hover(&mut s);
s.preview_memo.checks() - before
};
let few = checks(3);
assert!(few > 0, "a hover asks the memo");
assert_eq!(checks(60), few, "a check compares the whole selection: one per object is quadratic");
}
#[test]
fn hovering_over_an_unchanged_document_measures_nothing_again() {
// A selected square with Offset Path 10, drawn from 90 to 210, with Use Preview Bounds and Smart