Optimize BidiParagraphs with ASCII fast path (#408)

* Optimize BidiParagraphs with ASCII fast path - Added fast path for ASCII text that avoids BidiInfo allocation - Added some text shaping benchmarks

* refactor: fix clippy warnings and cleanup imports
This commit is contained in:
romanstingler 2025-08-11 21:15:09 +02:00 committed by GitHub
parent de355a1fd9
commit e80dbc3607
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 196 additions and 30 deletions

View file

@ -0,0 +1,121 @@
use cosmic_text as ct;
use cosmic_text::BidiParagraphs;
use criterion::{black_box, criterion_group, criterion_main, Criterion};
fn bench_ascii_fast_path(c: &mut Criterion) {
let mut fs = ct::FontSystem::new();
let mut buffer = ct::Buffer::new(&mut fs, ct::Metrics::new(14.0, 20.0));
buffer.set_size(&mut fs, Some(500.0), None);
let ascii_text = "Pure ASCII text for BidiParagraphs optimization testing.\n".repeat(50);
c.bench_function("ShapeLine/ASCII Fast Path", |b| {
b.iter(|| {
buffer.set_text(
&mut fs,
black_box(&ascii_text),
&ct::Attrs::new(),
ct::Shaping::Advanced,
);
buffer.shape_until_scroll(&mut fs, false);
});
});
}
fn bench_bidi_processing(c: &mut Criterion) {
let mut fs = ct::FontSystem::new();
let mut buffer = ct::Buffer::new(&mut fs, ct::Metrics::new(14.0, 20.0));
buffer.set_size(&mut fs, Some(500.0), None);
let bidi_text = "Mixed English and العربية النص العربي text for BiDi testing.\nThis tests adjust_levels and combined BiDi optimizations.\n".repeat(30);
c.bench_function("ShapeLine/BiDi Processing", |b| {
b.iter(|| {
buffer.set_text(
&mut fs,
black_box(&bidi_text),
&ct::Attrs::new(),
ct::Shaping::Advanced,
);
buffer.shape_until_scroll(&mut fs, false);
});
});
}
fn bench_layout_heavy(c: &mut Criterion) {
let mut fs = ct::FontSystem::new();
let mut buffer = ct::Buffer::new(&mut fs, ct::Metrics::new(14.0, 20.0));
buffer.set_size(&mut fs, Some(500.0), None);
let layout_text = "This is a very long line that will wrap multiple times and stress the reorder optimization through intensive layout processing with comprehensive buffer reuse testing. ".repeat(30);
c.bench_function("ShapeLine/Layout Heavy", |b| {
b.iter(|| {
buffer.set_text(
&mut fs,
black_box(&layout_text),
&ct::Attrs::new(),
ct::Shaping::Advanced,
);
buffer.shape_until_scroll(&mut fs, false);
});
});
}
fn bench_combined_stress(c: &mut Criterion) {
let mut fs = ct::FontSystem::new();
let mut buffer = ct::Buffer::new(&mut fs, ct::Metrics::new(14.0, 20.0));
buffer.set_size(&mut fs, Some(500.0), None);
let stress_text = format!("{}\n{}\n{}\n{}\n",
"ASCII line for BidiParagraphs optimization. ".repeat(15),
"Mixed English + العربية for BiDi optimizations. ".repeat(12),
"Very long wrapping line that will trigger reorder optimizations multiple times through intensive layout processing. ".repeat(8),
"Cache key generation line for ShapeRunKey optimization testing. ".repeat(10)
).repeat(10);
c.bench_function("ShapeLine/Combined Stress", |b| {
b.iter(|| {
buffer.set_text(
&mut fs,
black_box(&stress_text),
&ct::Attrs::new(),
ct::Shaping::Advanced,
);
buffer.shape_until_scroll(&mut fs, false);
});
});
}
fn bench_bidi_paragraphs_ascii(c: &mut Criterion) {
let ascii_text = "Simple ASCII text\nwith multiple lines\n".repeat(50);
c.bench_function("BidiParagraphs/ASCII", |b| {
b.iter(|| {
let paras = BidiParagraphs::new(black_box(&ascii_text));
black_box(paras.count());
});
});
}
fn bench_bidi_paragraphs_mixed(c: &mut Criterion) {
let mixed_text = "Mixed English and العربية text\nwith multiple lines\n".repeat(30);
c.bench_function("BidiParagraphs/Mixed", |b| {
b.iter(|| {
let paras = BidiParagraphs::new(black_box(&mixed_text));
black_box(paras.count());
});
});
}
criterion_group!(
benches,
bench_ascii_fast_path,
bench_bidi_processing,
bench_layout_heavy,
bench_combined_stress,
bench_bidi_paragraphs_ascii,
bench_bidi_paragraphs_mixed
);
criterion_main!(benches);