Take the deepest dirty widget from an ordered queue, not by scanning
The walk found the next widget to settle with `max_by_key` over the whole `needs_redraw` set, and `depth` is a hash lookup, so a frame did a lookup per marked widget per pop -- 131 depth reads for nine marks at seed 1 depth 8, 1,314 for 34, and 14,611 for 145. The set is scanned once now and kept in a `BTreeSet` keyed by depth, and every mark made while the walk runs goes through `mark`, which puts itself in place. The same three counts become 57, 160 and 436. Two things the scan gave for free are paid for explicitly: a widget that was settled inside an ancestor's draw, or deferred to one, is dropped when its entry comes up, and an entry whose widget has since changed depth -- a subtree that moved under a new parent -- is re-queued at the depth it now has. What is drawn does not change: widget draws are identical at every load measured. Median frame at seed 1, depth 8: 0.955 -> 0.843 ms with 145 marks, 0.668 -> 0.666 with 34, and seed 13's default load 5.19 -> 4.86 ms. Ties between equal depths now break by widget id rather than by hash order, which makes the walk deterministic; nothing in the order within one depth was ever relied on, since a widget at the same depth as another cannot contain it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
e6ba570d07
commit
3bf22935ce
2 files changed
+40
-15
No files matched your search
@@ -1,4 +1,4 @@
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
pub struct SlotId {
|
||||
idx: u32,
|
||||
genr: u32,
|
||||
|
||||
Reference in new issue
Block a user