Retain request dependencies only when discovery supplies the answer
This commit is contained in:
1 parent
8780b40bb7
commit
0e838e9dd1
7 files changed
+183
-50
No files matched your search
+82
-12
@@ -1,19 +1,22 @@
|
||||
//! What a resize frame costs and what it holds, on a tree the revision before
|
||||
//! #16 also builds.
|
||||
//!
|
||||
//! Deliberately written in the API subset `43ce8c7` and this branch share, so
|
||||
//! the same source can be dropped into an old worktree and measured there:
|
||||
//! that is the only like-for-like comparison with the code the retained
|
||||
//! layout replaced. The random tree cannot carry one, because the generator
|
||||
//! itself changed with the work.
|
||||
//! Text-layout workloads with stable paragraphs for comparisons across revisions.
|
||||
//! PR #19's base uses the older spelling of the fixed 40-pixel width and has
|
||||
//! no diagnostics. The random generator changed with layout, so it cannot
|
||||
//! provide the same workload across the full PR.
|
||||
//!
|
||||
//! ROWS=40 FRAMES=500 cargo test --release --test revision_cost \
|
||||
//! -- --ignored --nocapture resize_cost
|
||||
//! PHASE=edit ROWS=40 FRAMES=2000 cargo test --release --test revision_cost \
|
||||
//! -- --ignored --nocapture text_updates_cost
|
||||
//! ROWS=2000 cargo test --release --test revision_cost \
|
||||
//! -- --ignored --nocapture text_memory
|
||||
//!
|
||||
//! Wall time on this machine varies with CPU frequency; take the number from
|
||||
//! `perf stat -e instructions:u` on the test binary directly.
|
||||
//! `text_updates_cost` selects idle, repaint, edit, or scroll with `PHASE`.
|
||||
//! It alternates a short suffix for edits so later frames do not get a longer
|
||||
//! paragraph than earlier ones. These are CPU fixtures, with no GPU submission.
|
||||
//!
|
||||
//! Use repeated `perf stat -e instructions:u` runs on the executable directly;
|
||||
//! process totals include font loading and the cold frame, so compare identical
|
||||
//! row and frame counts. Wall time on this machine is not a stable comparison.
|
||||
|
||||
use iris::harness::Harness;
|
||||
use iris::prelude::*;
|
||||
@@ -137,9 +140,10 @@ fn resize_cost() {
|
||||
println!("paragraph {at}: {:?}", h.region(id));
|
||||
}
|
||||
|
||||
// Two widths in turn is the friendly case for anything that remembers an
|
||||
// answer, so `SWEEP=1` never repeats one -- a drag rather than a toggle.
|
||||
// The sweep cycles 256 widths, avoiding the two-width cache-friendly case.
|
||||
let sweep = env("SWEEP", 0_usize) != 0;
|
||||
#[cfg(feature = "layout-diagnostics")]
|
||||
let _ = iris::core::layout_diagnostics::take();
|
||||
let mut elapsed = Vec::with_capacity(frames);
|
||||
for frame in 0..frames {
|
||||
let narrower = match sweep {
|
||||
@@ -151,6 +155,11 @@ fn resize_cost() {
|
||||
h.frame();
|
||||
elapsed.push(start.elapsed().as_secs_f64() * 1000.0);
|
||||
}
|
||||
#[cfg(feature = "layout-diagnostics")]
|
||||
print!(
|
||||
"{}",
|
||||
iris::core::layout_diagnostics::take().per_frame(frames)
|
||||
);
|
||||
elapsed.sort_by(|a, b| a.partial_cmp(b).unwrap());
|
||||
println!(
|
||||
"resize: {frames} frames, min {:.3} ms, median {:.3} ms, p99 {:.3} ms, \
|
||||
@@ -203,3 +212,64 @@ fn text_memory() {
|
||||
}
|
||||
report("after settling");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore = "measurement, not a check"]
|
||||
fn text_updates_cost() {
|
||||
let rows = env("ROWS", 40_usize);
|
||||
let frames = env("FRAMES", 1000_usize);
|
||||
let phase = env("PHASE", String::from("edit"));
|
||||
assert!(rows > 0 && frames > 0);
|
||||
assert!(["idle", "repaint", "edit", "scroll"].contains(&phase.as_str()));
|
||||
let mut h = Harness::new(OUTPUT);
|
||||
let mut rng = Rng(1);
|
||||
let mut col = Span::empty(Dir::DOWN);
|
||||
let first = wtext(words(&mut rng, 12, 52))
|
||||
.size(16)
|
||||
.wrap(true)
|
||||
.add(&mut h.rsc);
|
||||
col.push(first.add_strong(&mut h.rsc));
|
||||
for _ in 1..rows {
|
||||
col.push(
|
||||
wtext(words(&mut rng, 12, 52))
|
||||
.size(16)
|
||||
.wrap(true)
|
||||
.add_strong(&mut h.rsc),
|
||||
);
|
||||
}
|
||||
let root = col.scrollable().add(&mut h.rsc);
|
||||
h.set_root(root);
|
||||
#[cfg(feature = "layout-diagnostics")]
|
||||
let _ = iris::core::layout_diagnostics::take();
|
||||
let original = h.rsc[first].content.to_string();
|
||||
let alternate = format!("{original} another word");
|
||||
let start = Instant::now();
|
||||
for frame in 0..frames {
|
||||
match phase.as_str() {
|
||||
"idle" => {}
|
||||
"repaint" => {
|
||||
let _ = h.rsc.widgets_mut().get_dyn_mut(first.id());
|
||||
}
|
||||
"edit" => {
|
||||
h.rsc[first].content.clear();
|
||||
h.rsc[first].content.push_str(if frame % 2 == 0 {
|
||||
&alternate
|
||||
} else {
|
||||
&original
|
||||
});
|
||||
}
|
||||
"scroll" => h.rsc[root].scroll(if frame % 2 == 0 { -12.0 } else { 12.0 }),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
h.frame();
|
||||
}
|
||||
println!(
|
||||
"{phase}: {rows} rows, {frames} frames, {:.1} ms",
|
||||
start.elapsed().as_secs_f64() * 1000.0
|
||||
);
|
||||
#[cfg(feature = "layout-diagnostics")]
|
||||
print!(
|
||||
"{}",
|
||||
iris::core::layout_diagnostics::take().per_frame(frames)
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user