diff --git a/docs/IRIS_EXTRACTION_HANDOFF.md b/docs/IRIS_EXTRACTION_HANDOFF.md index b967406..aa2335f 100644 --- a/docs/IRIS_EXTRACTION_HANDOFF.md +++ b/docs/IRIS_EXTRACTION_HANDOFF.md @@ -428,6 +428,30 @@ on `Widgets` and is inserted from places with no view of the tree, so either means a second structure inside the render state kept in step with it. For 4.7% that is not obviously worth the coupling. +**Going order-free costs more than the order now does.** Measured 2026-09-14 +with the depth carried, instructions per frame, on the same three loads: + +| | 32 dirty | 130 dirty | resize | +| --- | --- | --- | --- | +| ordered, no check (what is in) | 2.80M | 7.14M | 6.70M | +| ordered, with the check | 2.83M | 7.18M | 6.72M | +| arbitrary, with the check | 3.12M | 7.38M | 6.28M | + +So the check is nearly free where the order already makes it redundant, and +dropping the order costs 11% on a small dirty set. **Keeping the answer does +not help: it never hits.** The dirty set moves about once per check -- every +widget drawn takes its own mark out -- so an answer worked out against one +state of it is asked for against another, and a generation stamp invalidates +everything each time. Only a count maintained up the reader chain as marks come +and go would answer in O(1) without an invalidation to lose, and that is the +version still unbuilt. + +One thing not understood: the arbitrary-order rows above are consistently ~6% +cheaper with the kept answer in than without it, though the kept answer never +hits and only two lines differ between the builds. Nothing here rests on that +difference, but it means those two rows are worth re-measuring before anyone +builds on them. + **A frame that dirties many widgets at once was not being checked, and it is where the settle order shows.** `77bb75e` adds two generated cases -- every declared size changing together, and a spread of widgets marked for redraw