fix: review round — the Ok-but-no-op resets, the measure regression, and a
loop-of-one test F1 (HIGH). Gating the reset on Ok is not the same as gating it on "something changed". Six accepted commands changed nothing and reset every cursor anyway: SetAxis to the axis already held, HideItem on an already-hidden item, ShowItem on a never-hidden one, AddItem of an existing item (Category::add_item dedupes and returns Ok), and RemoveItem/RemoveCategory of something absent. Each now asks the state before mutating. The case that made it urgent needs no second client: TileSelect binds `r` to set-axis-for-tile row, which emits SetAxis with no comparison against the current axis, so `r` on a Row category sent the user's own cursor to the origin. F2 (REGRESSION this PR introduced). Naming a measure in the trailing `+` column at the bottom-right of a records grid sent the cursor home: AddItem now resets, inserts_a_column matches only NewCategory, and EnterAdvance at the bottom-right returns AbortChain with no SetSelected. The restore moves to BEFORE the advance, where an aborting advance cannot skip it -- gotcha 21's rule applied to the cursor rather than the mode -- which also subsumes the +cat arm's copy. F3. a_refused_model_command_invalidates_no_cursor named a class and tested one member; injecting reset_cursor into AddCategory's Err arm left it green. Now a table over all three refusable effects, and that injection fails it by name. F5. The benchmark could not reproduce its own figures: it took the mean over a few iterations, and review measured the same share at 8% and at 131% -- a part slower than the whole containing it, printed flat. It also passed (false, 2) where grid_of passes the view's (true, 0), so it timed a call that never happens. Now min-of-N with the view's own format, and a share above 100% prints UNSTABLE. Figures are stable across runs at ratio 1.2-1.5x, col_widths 45-49%. F6. The drg counts omitted the 8 simple_effect! invocations and misclassified AddItem at base through a regex that cannot see `app` newline `.model_state` -- doctrine(derive_then_verify) catching the person citing it. Correct: 57 effects, narrow set 32 -> 25, not 25 -> 17 of 49. The direction holds and is still the argument; the headline was overstated by about half again. Corrected in context/code/command.md and on the bead, not quietly restated. F9. a_model_command_that_leaves_the_active_view_alone_broadcasts_nothing asserts a ResetCursor broadcast, so the name read as a lie: ..._broadcasts_no_switch. F4 filed as improvise-pdvm: AddItem/RemoveItem declare CellData so layout_version does not bump while cursor_epoch does, and this PR's own reshape assertion is the first evidence for it. Related to improvise-75ld, same question other direction. Faults injected for every new guard: SetAxis's moved check, AddItem's fresh check, AddCategory's Err arm, and the pre-fix advance ordering ((0,0) vs (0,3)). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
+25
-15
@@ -3,6 +3,7 @@
|
||||
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
use improvise::format::parse_number_format;
|
||||
use improvise::model::cell::{CellKey, CellValue};
|
||||
use improvise::view::Axis;
|
||||
use improvise::workbook::Workbook;
|
||||
@@ -73,30 +74,33 @@ fn terminal_window() -> Viewport {
|
||||
}
|
||||
}
|
||||
|
||||
/// Min-of-N, not the mean: a mean over a handful of iterations is dominated by
|
||||
/// whatever else the machine was doing, which is how a share above 100% happens.
|
||||
fn time(iters: u32, app: &App, viewport: Viewport) -> Duration {
|
||||
for _ in 0..3 {
|
||||
let mut best = Duration::MAX;
|
||||
for _ in 0..iters.max(3) {
|
||||
let start = Instant::now();
|
||||
std::hint::black_box(project::grid_of(app, viewport));
|
||||
best = best.min(start.elapsed());
|
||||
}
|
||||
let start = Instant::now();
|
||||
for _ in 0..iters {
|
||||
std::hint::black_box(project::grid_of(app, viewport));
|
||||
}
|
||||
start.elapsed() / iters
|
||||
best
|
||||
}
|
||||
|
||||
/// `compute_col_widths` is whole-grid whatever the viewport says, so it is the part
|
||||
/// narrowing the cells loop cannot reach. Timed on its own for exactly that reason.
|
||||
/// narrowing the cells loop cannot reach. It must be timed with the arguments
|
||||
/// `grid_of` passes it, or the share is of a call that never happens.
|
||||
fn time_widths(iters: u32, app: &App) -> Duration {
|
||||
let layout = &app.layout;
|
||||
let model = &app.model_state.workbook.model;
|
||||
for _ in 0..3 {
|
||||
std::hint::black_box(compute_col_widths(model, layout, false, 2));
|
||||
let (comma, decimals) =
|
||||
parse_number_format(&app.model_state.workbook.active_view().number_format);
|
||||
let mut best = Duration::MAX;
|
||||
for _ in 0..iters.max(3) {
|
||||
let start = Instant::now();
|
||||
std::hint::black_box(compute_col_widths(model, layout, comma, decimals));
|
||||
best = best.min(start.elapsed());
|
||||
}
|
||||
let start = Instant::now();
|
||||
for _ in 0..iters {
|
||||
std::hint::black_box(compute_col_widths(model, layout, false, 2));
|
||||
}
|
||||
start.elapsed() / iters
|
||||
best
|
||||
}
|
||||
|
||||
fn case(label: &str, regions: usize, products: usize, measures: usize, iters: u32) {
|
||||
@@ -109,9 +113,15 @@ fn case(label: &str, regions: usize, products: usize, measures: usize, iters: u3
|
||||
let widths = time_widths(iters, &app);
|
||||
let ratio = full.as_secs_f64() / windowed.as_secs_f64().max(f64::EPSILON);
|
||||
let share = 100.0 * widths.as_secs_f64() / full.as_secs_f64().max(f64::EPSILON);
|
||||
// A part cannot take longer than the whole that contains it. Say so rather
|
||||
// than printing a number that reads like a measurement.
|
||||
let share = match share > 100.0 {
|
||||
true => "UNSTABLE".to_string(),
|
||||
false => format!("{share:.0}%"),
|
||||
};
|
||||
println!(
|
||||
"{label:<22} {rows:>5} x {cols:>3} = {cells:>7} cells whole-grid {full:>11.3?} \
|
||||
windowed {windowed:>11.3?} ratio {ratio:>4.1}x col_widths {widths:>11.3?} ({share:>4.0}% of the frame)"
|
||||
windowed {windowed:>11.3?} ratio {ratio:>4.1}x col_widths {widths:>11.3?} ({share} of the frame)"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user