From 4cbb242a5d56c1b2b8dfe52bd66484ce2252138e Mon Sep 17 00:00:00 2001 From: iris-ai <4+iris-ai@noreply.localhost> Date: Wed, 16 Sep 2026 14:01:52 -0400 Subject: [PATCH] Do not multiply by a part of nothing `lerp` is `a + (b - a) * f`, and `b - a` is nothing often enough to be worth asking: a box with the same pixels at both ends of an axis, a span with no fraction of one, a part of a subtree whose box did not move on that axis. `Fixed::scaled` is `mul` that answers a zero receiver without widening to `i64`, rounding and narrowing back, and `lerp` uses it -- so every lerp in layout gets it rather than the two places that were about to grow their own comparison. `many` over 500 frames: 1,705,786,553 instructions to 1,657,571,216, and 638.9M cycles against 657.9M, averaged over four runs each. Checked: fmt, clippy, 105 tests, all five shrinker cases at 300 seeds, and `tabs`, `text`, `random`, `minimal` and `view` byte-identical at 1920x1200. Co-Authored-By: Claude Opus 5 --- core/src/fixed.rs | 12 +++++++++++- core/src/ui/render_state.rs | 6 +++--- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/core/src/fixed.rs b/core/src/fixed.rs index 3488c00..625b77c 100644 --- a/core/src/fixed.rs +++ b/core/src/fixed.rs @@ -138,6 +138,16 @@ impl Fixed { Self(narrow(shift_round(self.0 as i64 * by.0 as i64, BY))) } + /// A part of a span that is often nothing: no part of nothing is + /// nothing, for the cost of a comparison rather than a widening + /// multiply and a rounding. + pub const fn scaled(self, by: Fixed) -> Self { + match self.0 == 0 { + true => self, + false => self.mul(by), + } + } + /// Repeated a whole number of times, which no grid rounds. pub const fn mul_int(self, by: i32) -> Self { Self(narrow(self.0 as i64 * by as i64)) @@ -179,7 +189,7 @@ impl Fixed { /// `from` and `to` a fraction of the way apart, the fraction being the /// receiver -- the argument order [`crate::util::LerpUtil`] already uses. pub const fn lerp(self, from: Fixed, to: Fixed) -> Fixed { - from.add(to.sub(from).mul(self)) + from.add(to.sub(from).scaled(self)) } pub const fn min(self, other: Self) -> Self { diff --git a/core/src/ui/render_state.rs b/core/src/ui/render_state.rs index 8d4c15a..5cfc0a6 100644 --- a/core/src/ui/render_state.rs +++ b/core/src/ui/render_state.rs @@ -1146,9 +1146,9 @@ impl AxisRemap { true => offset, false => offset / scale.extent, }; - let from_px = scale.from_px + scale.from_px_span.mul(fraction); - let to_rel = scale.to_rel + scale.to_rel_span.mul(fraction); - let to_px = scale.to_px + scale.to_px_span.mul(fraction); + let from_px = scale.from_px + scale.from_px_span.scaled(fraction); + let to_rel = scale.to_rel + scale.to_rel_span.scaled(fraction); + let to_px = scale.to_px + scale.to_px_span.scaled(fraction); Len::from_parts(to_rel, scalar.px - from_px + to_px) } }