perf(bench): introduce standardized 25-metric CAD and UI benchmark suite

- Add comprehensive performance benchmark harness in benches/performance_benchmarks.rs
  configured with harness = false in Cargo.toml (runs via cargo bench in --release,
  isolated from cargo test).
- Benchmark coverage across 25 distinct CAD & UI operations:
  * Entity Ingestion, GPU Wire Partitioning, Analytical & Wide/Tapered Arc Tessellation
  * 100x Zoom Navigation, Spatial InteractionIndex, Multi-mode Hit-Testing, OSnap Tracking
  * 2D Parametric Dogleg Constraint Solving, DXF Import/Export Throughput
  * UI Ribbon View Construction, Viewport Grid Projection, Grid Cache Evaluation
  * Themed SVG Icon Lookup Caching, Cold Extents AABB Calculation
  * Batch Entity Transformation, Draworder Depth Map Full/Patch, Delta-Undo Recording
- Expose internal calculation hooks with #[doc(hidden)] pub to prevent API leakage.
- Remove 644 lines of legacy, scattered ad-hoc #[test] #[ignore] benchmarks across src/.
- Add developer and regression documentation in benches/README.md.
This commit is contained in:
Karim Jerbi committed 2026-09-12 13:46:01 +01:00
1 parent 754cc89fab
commit 58c9fcb748
9 files changed
+1786 -651

No files matched your search

+1 -72
View File
@@ -1610,76 +1610,5 @@ mod tests {
assert!(ribbon.escape_extension());
assert_eq!(ribbon.open_dropdown, None);
}
/// Reproducible element-construction benchmark for the ribbon view. Run with:
/// `cargo test --lib --release -- --ignored --nocapture bench_ribbon_view_construction`
///
/// Times `Ribbon::view()` element construction — the dominant cost in the
/// cheap (non-render) part of a ribbon frame, and the thing Mission #4
/// reworked. `#[ignore]`d so normal runs stay silent; state is populated so
/// Auto-mode panels actually have four densities to build.
#[test]
#[ignore]
fn bench_ribbon_view_construction() {
use std::time::Instant;
use super::*;
let mut ribbon = Ribbon::new();
ribbon.set_styles(
vec![
"Standard".to_string(),
"Title".to_string(),
"Annotative".to_string(),
],
"Standard",
vec!["Standard".to_string()],
"Standard",
vec!["Standard".to_string()],
"Standard",
vec!["Standard".to_string()],
"Standard",
);
ribbon.set_layers(
vec![
LayerInfo {
name: "0".to_string(),
color: Color::TRANSPARENT,
visible: true,
frozen: false,
locked: false,
},
LayerInfo {
name: "DRAWING".to_string(),
color: Color::TRANSPARENT,
visible: true,
frozen: false,
locked: false,
},
],
"0",
);
ribbon.set_available_linetypes(vec![
LinetypeItem {
name: "Continuous".to_string(),
art: String::new(),
},
LinetypeItem {
name: "DASHED".to_string(),
art: String::new(),
},
]);
let n = 200u32;
// Warm-up for allocator/tree-slot settling before timing begins.
let _ = ribbon.view(false, false, 0, 0, false);
let start = Instant::now();
for _ in 0..n {
let _ = ribbon.view(false, false, 0, 0, false);
}
let per_frame = start.elapsed() / n;
println!(
"bench_ribbon_view_construction: {per_frame:?} per `Ribbon::view()` \
element build (n = {n}, release measurement recommended)"
);
}
}