From 7216d0e38633e3c30f6ed90b2577a86c56512765 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Tue, 6 May 2025 17:54:06 +0200 Subject: [PATCH] Use mimalloc for benchmarks (#7029) `mimalloc` is a _much_ faster allocator, especially important when doing a lot of small allocations (which egui does). We use `mimalloc` in Rerun, and I recommend everyone to use it. ## The difference it makes ![image](https://github.com/user-attachments/assets/b22e0025-bc5e-4b3c-94e0-74ce46e86f85) --- Cargo.lock | 22 ++++++++++++++++++++++ Cargo.toml | 1 + crates/egui/src/lib.rs | 3 +++ crates/egui_demo_app/Cargo.toml | 1 + crates/egui_demo_app/src/main.rs | 3 +++ crates/egui_demo_lib/Cargo.toml | 3 ++- crates/egui_demo_lib/benches/benchmark.rs | 3 +++ crates/epaint/Cargo.toml | 1 + crates/epaint/benches/benchmark.rs | 3 +++ 9 files changed, 39 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 35ff4c9a..8354ad59 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1336,6 +1336,7 @@ dependencies = [ "env_logger", "image", "log", + "mimalloc", "poll-promise", "profiling", "puffin", @@ -1358,6 +1359,7 @@ dependencies = [ "egui", "egui_extras", "egui_kittest", + "mimalloc", "rand", "serde", "unicode_names2", @@ -1559,6 +1561,7 @@ dependencies = [ "emath", "epaint_default_fonts", "log", + "mimalloc", "nohash-hasher", "parking_lot", "profiling", @@ -2486,6 +2489,16 @@ version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" +[[package]] +name = "libmimalloc-sys" +version = "0.1.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec9d6fac27761dabcd4ee73571cdb06b7022dc99089acbe5435691edffaac0f4" +dependencies = [ + "cc", + "libc", +] + [[package]] name = "libredox" version = "0.1.3" @@ -2591,6 +2604,15 @@ dependencies = [ "paste", ] +[[package]] +name = "mimalloc" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "995942f432bbb4822a7e9c3faa87a695185b0d09273ba85f097b54f4e458f2af" +dependencies = [ + "libmimalloc-sys", +] + [[package]] name = "mime" version = "0.3.17" diff --git a/Cargo.toml b/Cargo.toml index 3b306176..d3adbd90 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -87,6 +87,7 @@ home = "0.5.9" image = { version = "0.25", default-features = false } kittest = { version = "0.1.0", git = "https://github.com/rerun-io/kittest", branch = "main" } log = { version = "0.4", features = ["std"] } +mimalloc = "0.1.46" nohash-hasher = "0.2" parking_lot = "0.12" pollster = "0.4" diff --git a/crates/egui/src/lib.rs b/crates/egui/src/lib.rs index f8842a1c..1025e776 100644 --- a/crates/egui/src/lib.rs +++ b/crates/egui/src/lib.rs @@ -400,6 +400,9 @@ //! profile-with-puffin = ["profiling/profile-with-puffin"] //! ``` //! +//! ## Custom allocator +//! egui apps can run significantly (~20%) faster by using a custom allocator, like [mimalloc](https://crates.io/crates/mimalloc) or [talc](https://crates.io/crates/talc). +//! #![allow(clippy::float_cmp)] #![allow(clippy::manual_range_contains)] diff --git a/crates/egui_demo_app/Cargo.toml b/crates/egui_demo_app/Cargo.toml index b3eeb565..5868ed48 100644 --- a/crates/egui_demo_app/Cargo.toml +++ b/crates/egui_demo_app/Cargo.toml @@ -86,6 +86,7 @@ env_logger = { version = "0.10", default-features = false, features = [ "auto-color", "humantime", ] } +mimalloc.workspace = true rfd = { version = "0.15.3", optional = true } # web: diff --git a/crates/egui_demo_app/src/main.rs b/crates/egui_demo_app/src/main.rs index 476ffdac..cf391ee9 100644 --- a/crates/egui_demo_app/src/main.rs +++ b/crates/egui_demo_app/src/main.rs @@ -4,6 +4,9 @@ #![allow(rustdoc::missing_crate_level_docs)] // it's an example #![allow(clippy::never_loop)] // False positive +#[global_allocator] +static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc; // Much faster allocator, can give 20% speedups: https://github.com/emilk/egui/pull/7029 + // When compiling natively: fn main() -> eframe::Result { for arg in std::env::args().skip(1) { diff --git a/crates/egui_demo_lib/Cargo.toml b/crates/egui_demo_lib/Cargo.toml index 77b8fdcb..61b35f2e 100644 --- a/crates/egui_demo_lib/Cargo.toml +++ b/crates/egui_demo_lib/Cargo.toml @@ -56,8 +56,9 @@ serde = { workspace = true, optional = true } [dev-dependencies] criterion.workspace = true -egui_kittest = { workspace = true, features = ["wgpu", "snapshot"] } egui = { workspace = true, features = ["default_fonts"] } +egui_kittest = { workspace = true, features = ["wgpu", "snapshot"] } +mimalloc.workspace = true # for benchmarks rand = "0.9" [[bench]] diff --git a/crates/egui_demo_lib/benches/benchmark.rs b/crates/egui_demo_lib/benches/benchmark.rs index 2b9a2cc0..b511f0de 100644 --- a/crates/egui_demo_lib/benches/benchmark.rs +++ b/crates/egui_demo_lib/benches/benchmark.rs @@ -8,6 +8,9 @@ use egui::{Button, Id, RichText, TextureId, Ui, UiBuilder, Vec2}; use egui_demo_lib::LOREM_IPSUM_LONG; use rand::Rng as _; +#[global_allocator] +static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc; // Much faster allocator + /// 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). diff --git a/crates/epaint/Cargo.toml b/crates/epaint/Cargo.toml index b8b006d4..0dccd225 100644 --- a/crates/epaint/Cargo.toml +++ b/crates/epaint/Cargo.toml @@ -101,6 +101,7 @@ backtrace = { workspace = true, optional = true } [dev-dependencies] criterion.workspace = true +mimalloc.workspace = true similar-asserts.workspace = true diff --git a/crates/epaint/benches/benchmark.rs b/crates/epaint/benches/benchmark.rs index 444f81a1..14f4d2fa 100644 --- a/crates/epaint/benches/benchmark.rs +++ b/crates/epaint/benches/benchmark.rs @@ -5,6 +5,9 @@ use epaint::{ TessellationOptions, Tessellator, TextureAtlas, Vec2, }; +#[global_allocator] +static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc; // Much faster allocator + fn single_dashed_lines(c: &mut Criterion) { c.bench_function("single_dashed_lines", move |b| { b.iter(|| {