From 6ab8d4a67b94c2c30331ee52389cb1cffd5817a8 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Wed, 2 Sep 2026 20:10:45 +0200 Subject: [PATCH 1/3] Add random walk performance demo --- Cargo.lock | 193 +++++++++++++++++++++- examples/performance/README.md | 3 +- examples/performance/screenshot.png | 4 +- examples/performance/screenshot_thumb.png | 4 +- examples/performance/src/app.rs | 75 +++------ examples/performance/src/lib.rs | 4 +- examples_utils/Cargo.toml | 1 + examples_utils/src/lib.rs | 26 +++ 8 files changed, 249 insertions(+), 61 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8c8e2f9b..9b2c7d6f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -162,6 +162,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "alloca" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5a7d05ea6aea7e9e64d25b9156ba2fee3fdd659e34e41063cd2fc7cd020d7f4" +dependencies = [ + "cc", +] + [[package]] name = "allocator-api2" version = "0.2.21" @@ -202,6 +211,12 @@ dependencies = [ "libc", ] +[[package]] +name = "anes" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" + [[package]] name = "anstream" version = "1.0.0" @@ -709,6 +724,12 @@ dependencies = [ "wayland-client", ] +[[package]] +name = "cast" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" + [[package]] name = "cc" version = "1.4.0" @@ -742,6 +763,58 @@ dependencies = [ "libc", ] +[[package]] +name = "ciborium" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" +dependencies = [ + "ciborium-io", + "ciborium-ll", + "serde", +] + +[[package]] +name = "ciborium-io" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" + +[[package]] +name = "ciborium-ll" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" +dependencies = [ + "ciborium-io", + "half", +] + +[[package]] +name = "clap" +version = "4.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "473c7e07f409a8d772161724aa8db6a765a2532a70f9667eeb7b49d3d02fbdca" +dependencies = [ + "clap_builder", +] + +[[package]] +name = "clap_builder" +version = "4.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b48fea5a88e9ae728a2dcbedbfc0e730f7d60da42e1cb049a83c9fb8b789889" +dependencies = [ + "anstyle", + "clap_lex", +] + +[[package]] +name = "clap_lex" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" + [[package]] name = "clipboard-win" version = "5.4.1" @@ -855,6 +928,39 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "criterion" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "950046b2aa2492f9a536f5f4f9a3de7b9e2476e575e05bd6c333371add4d98f3" +dependencies = [ + "alloca", + "anes", + "cast", + "ciborium", + "clap", + "criterion-plot", + "itertools 0.13.0", + "num-traits", + "oorandom", + "page_size", + "regex", + "serde", + "serde_json", + "tinytemplate", + "walkdir", +] + +[[package]] +name = "criterion-plot" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8d80a2f4f5b554395e47b5d8305bc3d27813bacb73493eb1001e8f76dae29ea" +dependencies = [ + "cast", + "itertools 0.13.0", +] + [[package]] name = "crossbeam-deque" version = "0.8.7" @@ -1107,7 +1213,7 @@ dependencies = [ "bitflags 2.13.1", "emath", "epaint", - "itertools", + "itertools 0.15.0", "log", "nohash-hasher", "profiling", @@ -1202,12 +1308,14 @@ version = "0.37.0" dependencies = [ "ahash", "assertables", + "criterion", "document-features", "egui", "egui_kittest", "emath", "env_logger", "log", + "performance", "serde", ] @@ -1378,6 +1486,7 @@ dependencies = [ "eframe", "egui", "egui_kittest", + "egui_plot", ] [[package]] @@ -1969,6 +2078,15 @@ dependencies = [ "examples_utils", ] +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + [[package]] name = "itertools" version = "0.15.0" @@ -1978,6 +2096,12 @@ dependencies = [ "either", ] +[[package]] +name = "itoa" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + [[package]] name = "jiff" version = "0.2.35" @@ -2740,6 +2864,12 @@ version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" +[[package]] +name = "oorandom" +version = "11.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e" + [[package]] name = "open" version = "5.4.0" @@ -2788,6 +2918,16 @@ dependencies = [ "ttf-parser", ] +[[package]] +name = "page_size" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30d5b2194ed13191c1999ae0704b7839fb18384fa22e49b57eeaa97d79ce40da" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "parking" version = "2.2.1" @@ -3426,6 +3566,19 @@ dependencies = [ "syn 3.0.3", ] +[[package]] +name = "serde_json" +version = "1.0.151" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + [[package]] name = "serde_repr" version = "0.1.21" @@ -3777,6 +3930,16 @@ dependencies = [ "zerovec", ] +[[package]] +name = "tinytemplate" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" +dependencies = [ + "serde", + "serde_json", +] + [[package]] name = "toml" version = "1.1.4+spec-1.1.0" @@ -4417,6 +4580,22 @@ dependencies = [ "web-sys", ] +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + [[package]] name = "winapi-util" version = "0.1.11" @@ -4426,6 +4605,12 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + [[package]] name = "windows" version = "0.62.2" @@ -5031,6 +5216,12 @@ dependencies = [ "syn 2.0.119", ] +[[package]] +name = "zmij" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" + [[package]] name = "zune-core" version = "0.5.1" diff --git a/examples/performance/README.md b/examples/performance/README.md index 85749beb..af4da74d 100644 --- a/examples/performance/README.md +++ b/examples/performance/README.md @@ -1,6 +1,6 @@ # Performance Demo -This example demonstrates plotting performance with a large number of markers. Use the controls to adjust the number of markers and observe rendering performance. +This example demonstrates plotting performance with 10 random walks. Use the controls to adjust the number of values in each walk and observe rendering performance. ## Running @@ -17,4 +17,3 @@ trunk serve ![](screenshot.png) - diff --git a/examples/performance/screenshot.png b/examples/performance/screenshot.png index 44f48fa9..5029a516 100644 --- a/examples/performance/screenshot.png +++ b/examples/performance/screenshot.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0711a2241b8864b9c53fd5cff0c3fc7be40fd3b5c6a636b8ee7f7b19f1b19491 -size 28238 +oid sha256:6427f5d3253fef27b3ba90ed6add740239bccee06b91d2d44dbb371923e9c27a +size 283036 diff --git a/examples/performance/screenshot_thumb.png b/examples/performance/screenshot_thumb.png index e71a6511..61110792 100644 --- a/examples/performance/screenshot_thumb.png +++ b/examples/performance/screenshot_thumb.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e945a16af57b936d720854655f55759e60aded3164dd8546b023fa8de3781df9 -size 7876 +oid sha256:44edf7c108de20f58f612cc57c0d4c0df9540ccae7f41f039c4e21334503d8eb +size 27107 diff --git a/examples/performance/src/app.rs b/examples/performance/src/app.rs index b9bce3d6..15ed5f1c 100644 --- a/examples/performance/src/app.rs +++ b/examples/performance/src/app.rs @@ -1,53 +1,40 @@ use eframe::egui; use eframe::egui::Response; -use egui_plot::MarkerShape; +use egui_plot::Line; use egui_plot::Plot; -use egui_plot::Points; +use egui_plot::PlotPoint; +use examples_utils::random_walk; -/// Simple LCG pseudo-random number generator. Returns a value in [0.0, 1.0]. -fn rng(state: &mut u64) -> f64 { - let mut x = *state; - x ^= x << 13; - x ^= x >> 7; - x ^= x << 17; - *state = x; - (x as f64) / (u64::MAX as f64) -} - -fn make_markers(target_count: usize) -> Vec<[f64; 2]> { - let mut state = 42u64; - (0..target_count).map(|_| [rng(&mut state), rng(&mut state)]).collect() -} +const NUM_WALKS: usize = 10; +const DEFAULT_VALUES_PER_WALK: usize = 20_000; pub struct PerformanceDemo { - target_count: usize, - marker_radius: f32, - markers: Vec<[f64; 2]>, - marker_shape: MarkerShape, + values_per_walk: usize, + walks: Vec>, } impl Default for PerformanceDemo { fn default() -> Self { Self { - target_count: 100, - marker_radius: 1.0, - markers: make_markers(100), - marker_shape: MarkerShape::Circle, + values_per_walk: DEFAULT_VALUES_PER_WALK, + walks: make_walks(DEFAULT_VALUES_PER_WALK), } } } +fn make_walks(values_per_walk: usize) -> Vec> { + (0..NUM_WALKS) + .map(|walk_index| random_walk(walk_index as u64 + 1, values_per_walk)) + .collect() +} + impl PerformanceDemo { pub fn show_plot(&self, ui: &mut egui::Ui) -> Response { Plot::new("performance_demo") - .data_aspect(1.0) .show(ui, |plot_ui| { - plot_ui.points( - Points::new("markers", self.markers.clone()) - .radius(self.marker_radius) - .shape(self.marker_shape) - .filled(true), - ); + for (walk_index, walk) in self.walks.iter().enumerate() { + plot_ui.line(Line::new(format!("Walk {walk_index}"), walk.as_slice())); + } }) .response } @@ -57,38 +44,22 @@ impl PerformanceDemo { let fps = (1.0 / ui.input(|i| i.stable_dt)).round(); ui.horizontal(|ui| { - ui.label("Markers:"); + ui.label("Values per walk:"); if ui .add( - egui::DragValue::new(&mut self.target_count) + egui::DragValue::new(&mut self.values_per_walk) .speed(100) - .range(100..=10_000_000), + .range(1..=10_000_000), ) .changed() { - self.markers = make_markers(self.target_count); + self.walks = make_walks(self.values_per_walk); } - ui.label("Radius:"); - ui.add( - egui::DragValue::new(&mut self.marker_radius) - .speed(0.1) - .range(0.5..=5.0), - ); - - ui.label("Shape:"); - egui::ComboBox::from_id_salt("marker_shape") - .selected_text(format!("{:?}", self.marker_shape)) - .show_ui(ui, |ui| { - for shape in MarkerShape::all() { - ui.selectable_value(&mut self.marker_shape, shape, format!("{shape:?}")); - } - }); - ui.label(format!("FPS: {fps}")); }); - ui.label("Note: Less than 100k markers should work fine, beyond that may cause issues."); + ui.label(format!("{NUM_WALKS} random walks are shown.")); ui.response() } } diff --git a/examples/performance/src/lib.rs b/examples/performance/src/lib.rs index 076bbd34..253d1e25 100644 --- a/examples/performance/src/lib.rs +++ b/examples/performance/src/lib.rs @@ -16,11 +16,11 @@ impl PlotExample for PerformanceDemo { } fn description(&self) -> &'static str { - "This example demonstrates plotting performance with a large number of markers. Use the controls to adjust the number of markers and observe rendering performance." + "This example demonstrates plotting performance with 10 random walks. Use the controls to adjust the number of values in each walk and observe rendering performance." } fn tags(&self) -> &'static [&'static str] { - &["performance", "markers"] + &["lines", "performance"] } fn thumbnail_bytes(&self) -> &'static [u8] { diff --git a/examples_utils/Cargo.toml b/examples_utils/Cargo.toml index a1607489..e207c517 100644 --- a/examples_utils/Cargo.toml +++ b/examples_utils/Cargo.toml @@ -10,6 +10,7 @@ publish = false eframe = { workspace = true, default-features = false } egui = { workspace = true } egui_kittest = { workspace = true, features = ["snapshot", "eframe"] } +egui_plot.workspace = true [target.'cfg(not(target_arch = "wasm32"))'.dependencies] egui_kittest = { workspace = true, features = ["wgpu"] } diff --git a/examples_utils/src/lib.rs b/examples_utils/src/lib.rs index 792233fb..337251f0 100644 --- a/examples_utils/src/lib.rs +++ b/examples_utils/src/lib.rs @@ -1,4 +1,30 @@ use eframe::egui; +use egui_plot::PlotPoint; + +/// Generates a deterministic random walk with `num_values` points. +/// +/// This is useful for plot examples and benchmarks that need representative +/// line data without relying on an external random-number generator. +pub fn random_walk(seed: u64, num_values: usize) -> Vec { + let mut state = seed; + let mut y = 0.0; + + (0..num_values) + .map(|x| { + y += random_unit(&mut state) - 0.5; + PlotPoint::new(x as f64, y) + }) + .collect() +} + +fn random_unit(state: &mut u64) -> f64 { + let mut value = (*state).max(1); + value ^= value << 13; + value ^= value >> 7; + value ^= value << 17; + *state = value; + value as f64 / u64::MAX as f64 +} /// Trait for examples that can be displayed in the demo gallery. pub trait PlotExample { From 2e9d3a678866335f6801fbd530bb0a90e5ecea3b Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Wed, 2 Sep 2026 20:10:45 +0200 Subject: [PATCH 2/3] Benchmark random walk plots --- egui_plot/Cargo.toml | 7 ++++++ egui_plot/benches/performance.rs | 41 ++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 egui_plot/benches/performance.rs diff --git a/egui_plot/Cargo.toml b/egui_plot/Cargo.toml index 624f318c..788b2b60 100644 --- a/egui_plot/Cargo.toml +++ b/egui_plot/Cargo.toml @@ -48,6 +48,13 @@ serde = { workspace = true, optional = true } [dev-dependencies] assertables.workspace = true +criterion = { version = "0.8.2", default-features = false } +egui = { workspace = true, features = ["default_fonts"] } egui_kittest.workspace = true env_logger.workspace = true log.workspace = true +performance.workspace = true + +[[bench]] +name = "performance" +harness = false diff --git a/egui_plot/benches/performance.rs b/egui_plot/benches/performance.rs new file mode 100644 index 00000000..1b8a091d --- /dev/null +++ b/egui_plot/benches/performance.rs @@ -0,0 +1,41 @@ +use criterion::Criterion; +use criterion::criterion_group; +use criterion::criterion_main; +use egui::RawInput; +use performance::PerformanceDemo; + +fn performance_demo(c: &mut Criterion) { + let ctx = egui::Context::default(); + let demo = PerformanceDemo::default(); + + c.bench_function("random_walks_with_tessellate__realistic", |b| { + b.iter(|| { + let mut full_output = ctx.run_ui(RawInput::default(), |ui| { + demo.show_plot(ui); + }); + ctx.tessellate(full_output.shapes, full_output.pixels_per_point); + + full_output.textures_delta.clear(); + }); + }); + + c.bench_function("random_walks_no_tessellate", |b| { + b.iter(|| { + let output = ctx.run_ui(RawInput::default(), |ui| { + demo.show_plot(ui); + }); + output.drop_without_applying_deltas(); + }); + }); + + let full_output = ctx.run_ui(RawInput::default(), |ui| { + demo.show_plot(ui); + }); + c.bench_function("random_walks_only_tessellate", |b| { + b.iter(|| ctx.tessellate(full_output.shapes.clone(), full_output.pixels_per_point)); + }); + full_output.drop_without_applying_deltas(); +} + +criterion_group!(benches, performance_demo); +criterion_main!(benches); From 2572466134bda13c52365429ae05eb23f856b7ec Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Wed, 2 Sep 2026 20:18:31 +0200 Subject: [PATCH 3/3] Split performance examples by plot type --- Cargo.lock | 17 +++- Cargo.toml | 3 +- demo/Cargo.toml | 3 +- demo/src/app.rs | 3 +- egui_plot/Cargo.toml | 2 +- egui_plot/benches/performance.rs | 4 +- examples/performance/src/main.rs | 4 - .../Cargo.toml | 2 +- .../README.md | 7 +- .../screenshot.png | 0 .../screenshot_thumb.png | 0 .../src/app.rs | 8 +- .../src/lib.rs | 8 +- examples/performance_lines/src/main.rs | 4 + examples/performance_markers/Cargo.toml | 23 +++++ examples/performance_markers/README.md | 18 ++++ examples/performance_markers/screenshot.png | 3 + .../performance_markers/screenshot_thumb.png | 3 + examples/performance_markers/src/app.rs | 94 +++++++++++++++++++ examples/performance_markers/src/lib.rs | 41 ++++++++ examples/performance_markers/src/main.rs | 4 + 21 files changed, 225 insertions(+), 26 deletions(-) delete mode 100644 examples/performance/src/main.rs rename examples/{performance => performance_lines}/Cargo.toml (95%) rename examples/{performance => performance_lines}/README.md (74%) rename examples/{performance => performance_lines}/screenshot.png (100%) rename examples/{performance => performance_lines}/screenshot_thumb.png (100%) rename examples/{performance => performance_lines}/src/app.rs (92%) rename examples/{performance => performance_lines}/src/lib.rs (86%) create mode 100644 examples/performance_lines/src/main.rs create mode 100644 examples/performance_markers/Cargo.toml create mode 100644 examples/performance_markers/README.md create mode 100644 examples/performance_markers/screenshot.png create mode 100644 examples/performance_markers/screenshot_thumb.png create mode 100644 examples/performance_markers/src/app.rs create mode 100644 examples/performance_markers/src/lib.rs create mode 100644 examples/performance_markers/src/main.rs diff --git a/Cargo.lock b/Cargo.lock index 9b2c7d6f..ef4c8110 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1073,7 +1073,8 @@ dependencies = [ "linked_axes", "log", "markers", - "performance", + "performance_lines", + "performance_markers", "plot_span", "save_plot", "stacked_bar", @@ -1315,7 +1316,7 @@ dependencies = [ "emath", "env_logger", "log", - "performance", + "performance_lines", "serde", ] @@ -2977,7 +2978,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] -name = "performance" +name = "performance_lines" +version = "0.1.0" +dependencies = [ + "eframe", + "egui_plot", + "env_logger", + "examples_utils", +] + +[[package]] +name = "performance_markers" version = "0.1.0" dependencies = [ "eframe", diff --git a/Cargo.toml b/Cargo.toml index 99769fcf..cc601afc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -41,7 +41,8 @@ legend_sort = { version = "0.1.0", path = "examples/legend_sort" } lines = { version = "0.1.0", path = "examples/lines" } linked_axes = { version = "0.1.0", path = "examples/linked_axes" } markers = { version = "0.1.0", path = "examples/markers" } -performance = { version = "0.1.0", path = "examples/performance" } +performance_lines = { version = "0.1.0", path = "examples/performance_lines" } +performance_markers = { version = "0.1.0", path = "examples/performance_markers" } plot_span = { version = "0.1.0", path = "examples/plot_span" } save_plot = { version = "0.1.0", path = "examples/save_plot" } stacked_bar = { version = "0.1.0", path = "examples/stacked_bar" } diff --git a/demo/Cargo.toml b/demo/Cargo.toml index c9d1e2a4..6797a48c 100644 --- a/demo/Cargo.toml +++ b/demo/Cargo.toml @@ -42,7 +42,8 @@ legend_sort.workspace = true lines.workspace = true linked_axes.workspace = true markers.workspace = true -performance.workspace = true +performance_lines.workspace = true +performance_markers.workspace = true plot_span.workspace = true save_plot.workspace = true stacked_bar.workspace = true diff --git a/demo/src/app.rs b/demo/src/app.rs index 249a4b65..543da370 100644 --- a/demo/src/app.rs +++ b/demo/src/app.rs @@ -55,7 +55,8 @@ impl DemoGallery { Box::new(lines::LineExample::default()), Box::new(linked_axes::LinkedAxesExample::default()), Box::new(markers::MarkerDemo::default()), - Box::new(performance::PerformanceDemo::default()), + Box::new(performance_lines::PerformanceLinesDemo::default()), + Box::new(performance_markers::PerformanceMarkersDemo::default()), Box::new(plot_span::PlotSpanDemo::default()), Box::new(save_plot::SavePlotExample::default()), Box::new(stacked_bar::StackedBarExample::default()), diff --git a/egui_plot/Cargo.toml b/egui_plot/Cargo.toml index 788b2b60..8c38a0e7 100644 --- a/egui_plot/Cargo.toml +++ b/egui_plot/Cargo.toml @@ -53,7 +53,7 @@ egui = { workspace = true, features = ["default_fonts"] } egui_kittest.workspace = true env_logger.workspace = true log.workspace = true -performance.workspace = true +performance_lines.workspace = true [[bench]] name = "performance" diff --git a/egui_plot/benches/performance.rs b/egui_plot/benches/performance.rs index 1b8a091d..a14376db 100644 --- a/egui_plot/benches/performance.rs +++ b/egui_plot/benches/performance.rs @@ -2,11 +2,11 @@ use criterion::Criterion; use criterion::criterion_group; use criterion::criterion_main; use egui::RawInput; -use performance::PerformanceDemo; +use performance_lines::PerformanceLinesDemo; fn performance_demo(c: &mut Criterion) { let ctx = egui::Context::default(); - let demo = PerformanceDemo::default(); + let demo = PerformanceLinesDemo::default(); c.bench_function("random_walks_with_tessellate__realistic", |b| { b.iter(|| { diff --git a/examples/performance/src/main.rs b/examples/performance/src/main.rs deleted file mode 100644 index cf7279d1..00000000 --- a/examples/performance/src/main.rs +++ /dev/null @@ -1,4 +0,0 @@ -use examples_utils::make_main; -use performance::PerformanceDemo; - -make_main!(PerformanceDemo); diff --git a/examples/performance/Cargo.toml b/examples/performance_lines/Cargo.toml similarity index 95% rename from examples/performance/Cargo.toml rename to examples/performance_lines/Cargo.toml index c14aff8c..5b5fa8b0 100644 --- a/examples/performance/Cargo.toml +++ b/examples/performance_lines/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "performance" +name = "performance_lines" version = "0.1.0" authors = ["egui_plot contributors"] license.workspace = true diff --git a/examples/performance/README.md b/examples/performance_lines/README.md similarity index 74% rename from examples/performance/README.md rename to examples/performance_lines/README.md index af4da74d..94a52793 100644 --- a/examples/performance/README.md +++ b/examples/performance_lines/README.md @@ -1,4 +1,4 @@ -# Performance Demo +# Performance Lines Demo This example demonstrates plotting performance with 10 random walks. Use the controls to adjust the number of values in each walk and observe rendering performance. @@ -6,14 +6,13 @@ This example demonstrates plotting performance with 10 random walks. Use the con Native ```sh -cargo run -p performance +cargo run -p performance_lines ``` Web (WASM) ```sh -cd examples/performance +cd examples/performance_lines trunk serve ``` ![](screenshot.png) - diff --git a/examples/performance/screenshot.png b/examples/performance_lines/screenshot.png similarity index 100% rename from examples/performance/screenshot.png rename to examples/performance_lines/screenshot.png diff --git a/examples/performance/screenshot_thumb.png b/examples/performance_lines/screenshot_thumb.png similarity index 100% rename from examples/performance/screenshot_thumb.png rename to examples/performance_lines/screenshot_thumb.png diff --git a/examples/performance/src/app.rs b/examples/performance_lines/src/app.rs similarity index 92% rename from examples/performance/src/app.rs rename to examples/performance_lines/src/app.rs index 15ed5f1c..4e6095fb 100644 --- a/examples/performance/src/app.rs +++ b/examples/performance_lines/src/app.rs @@ -8,12 +8,12 @@ use examples_utils::random_walk; const NUM_WALKS: usize = 10; const DEFAULT_VALUES_PER_WALK: usize = 20_000; -pub struct PerformanceDemo { +pub struct PerformanceLinesDemo { values_per_walk: usize, walks: Vec>, } -impl Default for PerformanceDemo { +impl Default for PerformanceLinesDemo { fn default() -> Self { Self { values_per_walk: DEFAULT_VALUES_PER_WALK, @@ -28,9 +28,9 @@ fn make_walks(values_per_walk: usize) -> Vec> { .collect() } -impl PerformanceDemo { +impl PerformanceLinesDemo { pub fn show_plot(&self, ui: &mut egui::Ui) -> Response { - Plot::new("performance_demo") + Plot::new("performance_lines_demo") .show(ui, |plot_ui| { for (walk_index, walk) in self.walks.iter().enumerate() { plot_ui.line(Line::new(format!("Walk {walk_index}"), walk.as_slice())); diff --git a/examples/performance/src/lib.rs b/examples/performance_lines/src/lib.rs similarity index 86% rename from examples/performance/src/lib.rs rename to examples/performance_lines/src/lib.rs index 253d1e25..78ec9ec2 100644 --- a/examples/performance/src/lib.rs +++ b/examples/performance_lines/src/lib.rs @@ -4,15 +4,15 @@ use eframe::egui; use examples_utils::PlotExample; mod app; -pub use app::PerformanceDemo; +pub use app::PerformanceLinesDemo; -impl PlotExample for PerformanceDemo { +impl PlotExample for PerformanceLinesDemo { fn name(&self) -> &'static str { - "performance" + "performance_lines" } fn title(&self) -> &'static str { - "Performance Demo" + "Performance Lines Demo" } fn description(&self) -> &'static str { diff --git a/examples/performance_lines/src/main.rs b/examples/performance_lines/src/main.rs new file mode 100644 index 00000000..f45d3582 --- /dev/null +++ b/examples/performance_lines/src/main.rs @@ -0,0 +1,4 @@ +use examples_utils::make_main; +use performance_lines::PerformanceLinesDemo; + +make_main!(PerformanceLinesDemo); diff --git a/examples/performance_markers/Cargo.toml b/examples/performance_markers/Cargo.toml new file mode 100644 index 00000000..637d502c --- /dev/null +++ b/examples/performance_markers/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "performance_markers" +version = "0.1.0" +authors = ["egui_plot contributors"] +license.workspace = true +edition.workspace = true +rust-version.workspace = true +publish = false + +[lints] +workspace = true + +[dependencies] +eframe = { workspace = true, features = ["default"] } +egui_plot.workspace = true +env_logger = { workspace = true, default-features = false, features = [ + "auto-color", + "humantime", +] } +examples_utils.workspace = true + +[package.metadata.cargo-shear] +ignored = ["env_logger"] # env_logger used by make_main! macro diff --git a/examples/performance_markers/README.md b/examples/performance_markers/README.md new file mode 100644 index 00000000..11a48bce --- /dev/null +++ b/examples/performance_markers/README.md @@ -0,0 +1,18 @@ +# Performance Markers Demo + +This example demonstrates plotting performance with a large number of markers. Use the controls to adjust the number of markers and observe rendering performance. + +## Running + +Native +```sh +cargo run -p performance_markers +``` + +Web (WASM) +```sh +cd examples/performance_markers +trunk serve +``` + +![](screenshot.png) diff --git a/examples/performance_markers/screenshot.png b/examples/performance_markers/screenshot.png new file mode 100644 index 00000000..44f48fa9 --- /dev/null +++ b/examples/performance_markers/screenshot.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0711a2241b8864b9c53fd5cff0c3fc7be40fd3b5c6a636b8ee7f7b19f1b19491 +size 28238 diff --git a/examples/performance_markers/screenshot_thumb.png b/examples/performance_markers/screenshot_thumb.png new file mode 100644 index 00000000..e71a6511 --- /dev/null +++ b/examples/performance_markers/screenshot_thumb.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e945a16af57b936d720854655f55759e60aded3164dd8546b023fa8de3781df9 +size 7876 diff --git a/examples/performance_markers/src/app.rs b/examples/performance_markers/src/app.rs new file mode 100644 index 00000000..05d338cf --- /dev/null +++ b/examples/performance_markers/src/app.rs @@ -0,0 +1,94 @@ +use eframe::egui; +use eframe::egui::Response; +use egui_plot::MarkerShape; +use egui_plot::Plot; +use egui_plot::Points; + +/// Simple LCG pseudo-random number generator. Returns a value in [0.0, 1.0]. +fn rng(state: &mut u64) -> f64 { + let mut x = *state; + x ^= x << 13; + x ^= x >> 7; + x ^= x << 17; + *state = x; + x as f64 / u64::MAX as f64 +} + +fn make_markers(target_count: usize) -> Vec<[f64; 2]> { + let mut state = 42_u64; + (0..target_count).map(|_| [rng(&mut state), rng(&mut state)]).collect() +} + +pub struct PerformanceMarkersDemo { + target_count: usize, + marker_radius: f32, + markers: Vec<[f64; 2]>, + marker_shape: MarkerShape, +} + +impl Default for PerformanceMarkersDemo { + fn default() -> Self { + Self { + target_count: 100, + marker_radius: 1.0, + markers: make_markers(100), + marker_shape: MarkerShape::Circle, + } + } +} + +impl PerformanceMarkersDemo { + pub fn show_plot(&self, ui: &mut egui::Ui) -> Response { + Plot::new("performance_markers_demo") + .data_aspect(1.0) + .show(ui, |plot_ui| { + plot_ui.points( + Points::new("markers", self.markers.clone()) + .radius(self.marker_radius) + .shape(self.marker_shape) + .filled(true), + ); + }) + .response + } + + pub fn show_controls(&mut self, ui: &mut egui::Ui) -> Response { + ui.request_repaint(); // Continuous repaint for FPS counter + let fps = (1.0 / ui.input(|i| i.stable_dt)).round(); + + ui.horizontal(|ui| { + ui.label("Markers:"); + if ui + .add( + egui::DragValue::new(&mut self.target_count) + .speed(100) + .range(100..=10_000_000), + ) + .changed() + { + self.markers = make_markers(self.target_count); + } + + ui.label("Radius:"); + ui.add( + egui::DragValue::new(&mut self.marker_radius) + .speed(0.1) + .range(0.5..=5.0), + ); + + ui.label("Shape:"); + egui::ComboBox::from_id_salt("marker_shape") + .selected_text(format!("{:?}", self.marker_shape)) + .show_ui(ui, |ui| { + for shape in MarkerShape::all() { + ui.selectable_value(&mut self.marker_shape, shape, format!("{shape:?}")); + } + }); + + ui.label(format!("FPS: {fps}")); + }); + + ui.label("Note: Less than 100k markers should work fine, beyond that may cause issues."); + ui.response() + } +} diff --git a/examples/performance_markers/src/lib.rs b/examples/performance_markers/src/lib.rs new file mode 100644 index 00000000..92fb4c67 --- /dev/null +++ b/examples/performance_markers/src/lib.rs @@ -0,0 +1,41 @@ +#![cfg_attr(doc, doc = include_str!("../README.md"))] + +use eframe::egui; +use examples_utils::PlotExample; + +mod app; +pub use app::PerformanceMarkersDemo; + +impl PlotExample for PerformanceMarkersDemo { + fn name(&self) -> &'static str { + "performance_markers" + } + + fn title(&self) -> &'static str { + "Performance Markers Demo" + } + + fn description(&self) -> &'static str { + "This example demonstrates plotting performance with a large number of markers. Use the controls to adjust the number of markers and observe rendering performance." + } + + fn tags(&self) -> &'static [&'static str] { + &["markers", "performance"] + } + + fn thumbnail_bytes(&self) -> &'static [u8] { + include_bytes!("../screenshot_thumb.png") + } + + fn code_bytes(&self) -> &'static [u8] { + include_bytes!("./app.rs") + } + + fn show_ui(&mut self, ui: &mut egui::Ui) -> egui::Response { + self.show_plot(ui) + } + + fn show_controls(&mut self, ui: &mut egui::Ui) -> egui::Response { + self.show_controls(ui) + } +} diff --git a/examples/performance_markers/src/main.rs b/examples/performance_markers/src/main.rs new file mode 100644 index 00000000..a485074a --- /dev/null +++ b/examples/performance_markers/src/main.rs @@ -0,0 +1,4 @@ +use examples_utils::make_main; +use performance_markers::PerformanceMarkersDemo; + +make_main!(PerformanceMarkersDemo);