Lots of claude-driven performance work.
This commit is contained in:
94
lib/ui/benches/layout_bench.rs
Normal file
94
lib/ui/benches/layout_bench.rs
Normal file
@@ -0,0 +1,94 @@
|
||||
use criterion::{Criterion, criterion_group, criterion_main};
|
||||
use ruin_ui::{
|
||||
Color, Element, FlexDirection, LayoutCache, TextStyle, TextSystem, UiSize,
|
||||
layout_snapshot_with_cache,
|
||||
};
|
||||
|
||||
fn text_style() -> TextStyle {
|
||||
TextStyle::new(14.0, Color::rgb(0xFF, 0xFF, 0xFF))
|
||||
}
|
||||
|
||||
fn make_column_tree(n: usize) -> Element {
|
||||
let mut root = Element::new().direction(FlexDirection::Column);
|
||||
for i in 0..n {
|
||||
root = root.child(Element::text(format!("item {i}"), text_style()));
|
||||
}
|
||||
root
|
||||
}
|
||||
|
||||
/// Static tree — nothing changes between frames. After one warmup frame, all
|
||||
/// subsequent frames should be near-zero cost (all cache hits).
|
||||
fn bench_static_tree(c: &mut Criterion) {
|
||||
let mut text_system = TextSystem::new();
|
||||
let mut layout_cache = LayoutCache::new();
|
||||
let root = make_column_tree(200);
|
||||
let size = UiSize::new(400.0, 4000.0);
|
||||
|
||||
// Warm up cache.
|
||||
layout_snapshot_with_cache(1, size, &root, &mut text_system, &mut layout_cache);
|
||||
|
||||
c.bench_function("layout_static_200_nodes", |b| {
|
||||
let mut version = 2u64;
|
||||
b.iter(|| {
|
||||
version += 1;
|
||||
layout_snapshot_with_cache(version, size, &root, &mut text_system, &mut layout_cache)
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/// 200 nodes, one text content changes per frame — only one cache miss expected.
|
||||
fn bench_single_change(c: &mut Criterion) {
|
||||
let mut text_system = TextSystem::new();
|
||||
let mut layout_cache = LayoutCache::new();
|
||||
let size = UiSize::new(400.0, 4000.0);
|
||||
|
||||
// Initial warmup.
|
||||
let root = make_column_tree(200);
|
||||
layout_snapshot_with_cache(1, size, &root, &mut text_system, &mut layout_cache);
|
||||
|
||||
c.bench_function("layout_single_change_200_nodes", |b| {
|
||||
let mut counter = 0usize;
|
||||
let mut version = 2u64;
|
||||
b.iter(|| {
|
||||
counter += 1;
|
||||
version += 1;
|
||||
let mut tree = make_column_tree(200);
|
||||
tree.children[100] = Element::text(format!("changed {counter}"), text_style());
|
||||
layout_snapshot_with_cache(version, size, &tree, &mut text_system, &mut layout_cache)
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/// Scroll box with 500 items, 20 visible. Simulates a large list.
|
||||
fn bench_scroll_list(c: &mut Criterion) {
|
||||
let mut text_system = TextSystem::new();
|
||||
let mut layout_cache = LayoutCache::new();
|
||||
let item_height = 32.0;
|
||||
let viewport_height = 640.0;
|
||||
let n = 500;
|
||||
|
||||
let mut scroll_box = Element::scroll_box(0.0).width(400.0).height(viewport_height);
|
||||
for i in 0..n {
|
||||
scroll_box = scroll_box.child(
|
||||
Element::new()
|
||||
.height(item_height)
|
||||
.child(Element::text(format!("list item {i}"), text_style())),
|
||||
);
|
||||
}
|
||||
let root = Element::new().child(scroll_box);
|
||||
let size = UiSize::new(400.0, viewport_height);
|
||||
|
||||
// Warm up.
|
||||
layout_snapshot_with_cache(1, size, &root, &mut text_system, &mut layout_cache);
|
||||
|
||||
c.bench_function("layout_scroll_list_500_items", |b| {
|
||||
let mut version = 2u64;
|
||||
b.iter(|| {
|
||||
version += 1;
|
||||
layout_snapshot_with_cache(version, size, &root, &mut text_system, &mut layout_cache)
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
criterion_group!(benches, bench_static_tree, bench_single_change, bench_scroll_list);
|
||||
criterion_main!(benches);
|
||||
Reference in New Issue
Block a user