Move a whole box at once, since that is what a move does

Profiling a move by cycles rather than by instructions says the cost is not
where the last session recorded it. In `apply_scalar` the `i64` division is
**0.00%** of cycles and the multiply 1.5%: the time is in `saturating_add`,
which is five instructions and no vector form for an `i32`, and a box that
only moved does eight of them. Asking for them one scalar at a time, each
behind a match on which kind of move this is, gives the compiler four short
sequences where it had four adds in a row to pair up.

So a translation is now asked for once for the whole region -- which is what
a translation is -- and the match happens once above it rather than per
scalar. `many` over 500 frames: 684M cycles to 660M, and 1,815,666,327
instructions to 1,742,553,104.

Cycle counts are worth trusting here, which is the other thing to keep: three
runs of one binary varied 0.23%. It is wall time that varies 2x on this
machine, not the counters, and instructions alone cannot see a stall.

Checked: fmt, clippy, 105 tests, all five shrinker cases at 300 seeds, and
`tabs`, `text` and `random` byte-identical at 1920x1200.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
iris-aiandClaude Opus 5 committed 2026-09-16 13:50:58 -04:00
1 parent cb1bba4682
commit 1940e85c70
2 files changed
+28

No files matched your search

+20
View File
@@ -292,6 +292,15 @@ impl UiSpan {
pub const fn len(&self) -> Len {
self.end - self.start
}
/// Both ends by the same amount, which is what moving a box without
/// changing its length does to every part of it.
pub const fn translated(self, by: Len) -> Self {
Self {
start: self.start + by,
end: self.end + by,
}
}
}
#[repr(C)]
@@ -302,6 +311,17 @@ pub struct UiRegion {
}
impl UiRegion {
/// Every part of the box by the same amount on each axis. Done to the
/// whole region rather than an end at a time, because that is what it is
/// -- and because four adds in a row are four adds, where four asked for
/// separately are four sequences.
pub const fn translated(self, x: Len, y: Len) -> Self {
Self {
x: self.x.translated(x),
y: self.y.translated(y),
}
}
pub const FULL: Self = Self {
x: UiSpan::FULL,
y: UiSpan::FULL,
+8
View File
@@ -1090,6 +1090,14 @@ impl RegionRemap {
}
fn apply(&self, region: UiRegion) -> UiRegion {
// A box that only moved carries every part of itself by the same two
// amounts, and that is the common move. Asking it once for the whole
// region is what lets it be eight adds in a row rather than four
// sequences with a branch each -- measured, it is where the time in a
// move goes.
if let [AxisRemap::Translate(x), AxisRemap::Translate(y)] = self.axes {
return region.translated(x, y);
}
UiRegion {
x: self.axes[0].apply_span(region.x),
y: self.axes[1].apply_span(region.y),