From 22df7caf4deac7dfd4e43a81713b72de8898d18f Mon Sep 17 00:00:00 2001 From: Martin Ball Date: Fri, 23 Oct 2026 14:50:14 +0100 Subject: [PATCH] =?UTF-8?q?#3692:=20review=20=E2=80=94=20formats=20timing?= =?UTF-8?q?=20tests=20get=20a=20margin=20a=20busy=20CI=20machine=20can't?= =?UTF-8?q?=20break?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit many_formatted_leading_breaks_trim_quickly failed at its 2 s bound on a machine at load ~50 (it takes about a second there). Bounds now sit at least 10x over the fixed code's time on a loaded machine and far under the old code's on the same input (measured by running the pre-fix code, capped at 400 s): - HTML leading breaks: 2 s -> 20 s; ~1 s now, old trim ran past 6 minutes. - LaTeX nested multicolumn: 2 s -> 10 s; under 1 s now, old unwrapping took 213 s. - Markdown delimiters: 2 s -> 10 s; under 1 s now, old backwards search past 6 minutes. - Para::trim blank spans: 1 s -> 10 s; 0.16 s now, old Vec::remove(0) past 6 minutes. - repeated sheet headers: 2 s -> 10 s; 20 ms now, old numbering past 6 minutes. Co-Authored-By: Claude Opus 5.5 (1M context) Claude-Session: https://claude.ai/code/session_01CX1hMKX28764Lrx5moxs1o --- crates/formats/src/html.rs | 3 ++- crates/formats/src/latex.rs | 3 ++- crates/formats/src/markdown.rs | 3 ++- crates/formats/src/model.rs | 3 ++- crates/formats/src/sheet.rs | 3 ++- 5 files changed, 10 insertions(+), 5 deletions(-) diff --git a/crates/formats/src/html.rs b/crates/formats/src/html.rs index f1eb1693c..a3d76578c 100644 --- a/crates/formats/src/html.rs +++ b/crates/formats/src/html.rs @@ -2435,7 +2435,8 @@ mod tests { let html = format!("

{}x

", "

".repeat(100_000)); let t = std::time::Instant::now(); let f = parse(&html); - assert!(t.elapsed() < std::time::Duration::from_secs(2), "{:?}", t.elapsed()); + // About a second on a loaded machine; trimming one span at a time ran past 6 minutes. + assert!(t.elapsed() < std::time::Duration::from_secs(20), "{:?}", t.elapsed()); let texts: Vec = f.blocks.iter().filter_map(|b| if let FBlock::Para(p) = b { Some(p.text()) } else { None }).collect(); assert_eq!(texts, ["x"]); } diff --git a/crates/formats/src/latex.rs b/crates/formats/src/latex.rs index a79f3a9f0..d2c35f3cb 100644 --- a/crates/formats/src/latex.rs +++ b/crates/formats/src/latex.rs @@ -3264,7 +3264,8 @@ Caf\'e na\"ive \c{c}a \v{s}\'{e} and {\bfseries grouped bold} after. let src = format!("\\begin{{tabular}}{{l}}{}x{}\\\\\\end{{tabular}}", "\\multicolumn{1}{c}{".repeat(n), "}".repeat(n)); let t = std::time::Instant::now(); let f = parse(&src); - assert!(t.elapsed() < std::time::Duration::from_secs(2), "{:?}", t.elapsed()); + // Under a second on a loaded machine; unwrapping every wrapper took 213 s. + assert!(t.elapsed() < std::time::Duration::from_secs(10), "{:?}", t.elapsed()); assert!(f.blocks.iter().any(|b| matches!(b, FBlock::Table(_)))); // One or two wrappers, as written in real tables, are still read. let f = parse("\\begin{tabular}{ll}\\multicolumn{2}{c}{\\multirow{2}{*}{Both}}\\\\\\end{tabular}"); diff --git a/crates/formats/src/markdown.rs b/crates/formats/src/markdown.rs index 56d631e7a..9196c1968 100644 --- a/crates/formats/src/markdown.rs +++ b/crates/formats/src/markdown.rs @@ -2203,7 +2203,8 @@ mod tests { let src = "*_".repeat(200_000); let t = std::time::Instant::now(); let out = inl(&src); - assert!(t.elapsed() < std::time::Duration::from_secs(2), "{:?}", t.elapsed()); + // Under a second on a loaded machine; the backwards search ran past 6 minutes. + assert!(t.elapsed() < std::time::Duration::from_secs(10), "{:?}", t.elapsed()); let text: String = out.iter().filter_map(|i| if let Inline::Text(t, _) = i { Some(t.as_str()) } else { None }).collect(); assert!(text.chars().all(|c| matches!(c, '*' | '_')), "only delimiters come out"); // Literal delimiters still take the link of the text before them. diff --git a/crates/formats/src/model.rs b/crates/formats/src/model.rs index 61ae4aea5..ccc1f1c0c 100644 --- a/crates/formats/src/model.rs +++ b/crates/formats/src/model.rs @@ -1669,7 +1669,8 @@ mod tests { p.push_text(" x ", &Fmt::default()); let t = std::time::Instant::now(); p.trim(); - assert!(t.elapsed() < std::time::Duration::from_secs(1), "{:?}", t.elapsed()); + // A fraction of a second; `Vec::remove(0)` per span ran past 6 minutes. + assert!(t.elapsed() < std::time::Duration::from_secs(10), "{:?}", t.elapsed()); assert_eq!(p.inlines, vec![Inline::Text("x".into(), Fmt::default())]); // The first span left keeps its formatting and loses only its leading blanks. let mut p = Para::default(); diff --git a/crates/formats/src/sheet.rs b/crates/formats/src/sheet.rs index e3ff85f29..f7f300812 100644 --- a/crates/formats/src/sheet.rs +++ b/crates/formats/src/sheet.rs @@ -1252,7 +1252,8 @@ mod tests { let row = vec!["Name".to_string(); 5_000]; let t = std::time::Instant::now(); let names = field_names(&row); - assert!(t.elapsed() < std::time::Duration::from_secs(2), "{:?}", t.elapsed()); + // Milliseconds; the old numbering ran past 6 minutes. + assert!(t.elapsed() < std::time::Duration::from_secs(10), "{:?}", t.elapsed()); assert_eq!(names.len(), 5_000); assert_eq!(names[0], "Name"); assert_eq!(names[4_999], "Name 5000");