Add button benchmark (#6854)
This helped me benchmark the atomic layout (#5830) changes. I also realized that the label benchmark wasn't testing the painting, since the buttons at some point will be placed outside the screen_rect, meaning it won't be painted. This fixes it by benching the label in a child ui. The `label &str` benchmark went from 483 ns to 535 ns with these changes. EDIT: I fixed another benchmark problem, since the benchmark would show the same widget millions of times for a single frame, the WidgetRects hashmap would get huge, causing each iteration to slow down a bit more and causing the benchmark to have unreliable results. With this the `label &str` benchmark went from 535ns to 298ns. Also the `label format!` benchmark now takes almost the same time (302 ns). Before, it was a lot slower since it reused the same Context which already had millions of widget ids.
This commit is contained in:
parent
f2ce6424f3
commit
7d185acb41
|
|
@ -14,3 +14,19 @@ The demo library is a separate crate for three reasons:
|
||||||
* To remove the amount of code in `egui` proper.
|
* To remove the amount of code in `egui` proper.
|
||||||
* To make it easy for 3rd party egui integrations to use it for tests.
|
* To make it easy for 3rd party egui integrations to use it for tests.
|
||||||
- See for instance https://github.com/not-fl3/egui-miniquad/blob/master/examples/demo.rs
|
- See for instance https://github.com/not-fl3/egui-miniquad/blob/master/examples/demo.rs
|
||||||
|
|
||||||
|
This crate also contains benchmarks for egui.
|
||||||
|
Run them with
|
||||||
|
```bash
|
||||||
|
# Run all benchmarks
|
||||||
|
cargo bench -p egui_demo_lib
|
||||||
|
|
||||||
|
# Run a single benchmark
|
||||||
|
cargo bench -p egui_demo_lib "benchmark name"
|
||||||
|
|
||||||
|
# Profile benchmarks with cargo-flamegraph (--root flag is necessary for MacOS)
|
||||||
|
CARGO_PROFILE_BENCH_DEBUG=true cargo flamegraph --bench benchmark --root -p egui_demo_lib -- --bench "benchmark name"
|
||||||
|
|
||||||
|
# Profile with cargo-instruments
|
||||||
|
CARGO_PROFILE_BENCH_DEBUG=true cargo instruments --profile bench --bench benchmark -p egui_demo_lib -t time -- --bench "benchmark name"
|
||||||
|
```
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,20 @@
|
||||||
use std::fmt::Write as _;
|
use std::fmt::Write as _;
|
||||||
|
|
||||||
use criterion::{criterion_group, criterion_main, Criterion};
|
use criterion::{criterion_group, criterion_main, BatchSize, Criterion};
|
||||||
|
|
||||||
use egui::epaint::TextShape;
|
use egui::epaint::TextShape;
|
||||||
|
use egui::load::SizedTexture;
|
||||||
|
use egui::{Button, Id, TextureId, Ui, UiBuilder, Vec2};
|
||||||
use egui_demo_lib::LOREM_IPSUM_LONG;
|
use egui_demo_lib::LOREM_IPSUM_LONG;
|
||||||
use rand::Rng as _;
|
use rand::Rng as _;
|
||||||
|
|
||||||
|
/// Each iteration should be called in their own `Ui` with an intentional id clash,
|
||||||
|
/// to prevent the Context from building a massive map of `WidgetRects` (which would slow the test,
|
||||||
|
/// causing unreliable results).
|
||||||
|
fn create_benchmark_ui(ctx: &egui::Context) -> Ui {
|
||||||
|
Ui::new(ctx.clone(), Id::new("clashing_id"), UiBuilder::new())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn criterion_benchmark(c: &mut Criterion) {
|
pub fn criterion_benchmark(c: &mut Criterion) {
|
||||||
use egui::RawInput;
|
use egui::RawInput;
|
||||||
|
|
||||||
|
|
@ -55,17 +64,62 @@ pub fn criterion_benchmark(c: &mut Criterion) {
|
||||||
{
|
{
|
||||||
let ctx = egui::Context::default();
|
let ctx = egui::Context::default();
|
||||||
let _ = ctx.run(RawInput::default(), |ctx| {
|
let _ = ctx.run(RawInput::default(), |ctx| {
|
||||||
egui::CentralPanel::default().show(ctx, |ui| {
|
c.bench_function("label &str", |b| {
|
||||||
c.bench_function("label &str", |b| {
|
b.iter_batched_ref(
|
||||||
b.iter(|| {
|
|| create_benchmark_ui(ctx),
|
||||||
|
|ui| {
|
||||||
ui.label("the quick brown fox jumps over the lazy dog");
|
ui.label("the quick brown fox jumps over the lazy dog");
|
||||||
});
|
},
|
||||||
});
|
BatchSize::LargeInput,
|
||||||
c.bench_function("label format!", |b| {
|
);
|
||||||
b.iter(|| {
|
});
|
||||||
|
c.bench_function("label format!", |b| {
|
||||||
|
b.iter_batched_ref(
|
||||||
|
|| create_benchmark_ui(ctx),
|
||||||
|
|ui| {
|
||||||
ui.label("the quick brown fox jumps over the lazy dog".to_owned());
|
ui.label("the quick brown fox jumps over the lazy dog".to_owned());
|
||||||
});
|
},
|
||||||
});
|
BatchSize::LargeInput,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
let ctx = egui::Context::default();
|
||||||
|
let _ = ctx.run(RawInput::default(), |ctx| {
|
||||||
|
let mut group = c.benchmark_group("button");
|
||||||
|
|
||||||
|
// To ensure we have a valid image, let's use the font texture. The size
|
||||||
|
// shouldn't be important for this benchmark.
|
||||||
|
let image = SizedTexture::new(TextureId::default(), Vec2::splat(16.0));
|
||||||
|
|
||||||
|
group.bench_function("1_button_text", |b| {
|
||||||
|
b.iter_batched_ref(
|
||||||
|
|| create_benchmark_ui(ctx),
|
||||||
|
|ui| {
|
||||||
|
ui.add(Button::new("Hello World"));
|
||||||
|
},
|
||||||
|
BatchSize::LargeInput,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
group.bench_function("2_button_text_image", |b| {
|
||||||
|
b.iter_batched_ref(
|
||||||
|
|| create_benchmark_ui(ctx),
|
||||||
|
|ui| {
|
||||||
|
ui.add(Button::image_and_text(image, "Hello World"));
|
||||||
|
},
|
||||||
|
BatchSize::LargeInput,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
group.bench_function("3_button_text_image_right_text", |b| {
|
||||||
|
b.iter_batched_ref(
|
||||||
|
|| create_benchmark_ui(ctx),
|
||||||
|
|ui| {
|
||||||
|
ui.add(Button::image_and_text(image, "Hello World").right_text("⏵"));
|
||||||
|
},
|
||||||
|
BatchSize::LargeInput,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue