From 4808da44a2466facf4fb9e8a43f7a8d370a9c6b4 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Wed, 31 Mar 2021 17:06:12 +0200 Subject: [PATCH] Optimize: more inlining and more use of AHashMap No real gains, but it didn't hurt either --- egui/src/animation_manager.rs | 4 ++-- egui/src/context.rs | 1 + egui/src/input_state.rs | 8 ++++++++ egui/src/layers.rs | 6 +++++- egui/src/memory.rs | 3 +++ egui/src/response.rs | 7 +++++++ egui/src/widgets/plot.rs | 1 + egui_demo_lib/benches/benchmark.rs | 2 +- epaint/src/text/fonts.rs | 6 ++++-- 9 files changed, 32 insertions(+), 6 deletions(-) diff --git a/egui/src/animation_manager.rs b/egui/src/animation_manager.rs index e28ffa1b5..97e1bbfb9 100644 --- a/egui/src/animation_manager.rs +++ b/egui/src/animation_manager.rs @@ -1,10 +1,10 @@ -use std::collections::HashMap; +use epaint::ahash::AHashMap; use crate::{emath::remap_clamp, Id, InputState}; #[derive(Clone, Default)] pub(crate) struct AnimationManager { - bools: HashMap, + bools: AHashMap, } #[derive(Clone, Debug)] diff --git a/egui/src/context.rs b/egui/src/context.rs index e8d9a4006..17d5d71d2 100644 --- a/egui/src/context.rs +++ b/egui/src/context.rs @@ -385,6 +385,7 @@ impl Context { self.repaint_requests.store(times_to_repaint, SeqCst); } + #[inline(always)] pub fn input(&self) -> &InputState { &self.input } diff --git a/egui/src/input_state.rs b/egui/src/input_state.rs index 706bec79d..9b1ab0d06 100644 --- a/egui/src/input_state.rs +++ b/egui/src/input_state.rs @@ -393,28 +393,33 @@ impl PointerState { } /// How much the pointer moved compared to last frame, in points. + #[inline(always)] pub fn delta(&self) -> Vec2 { self.delta } /// Current velocity of pointer. + #[inline(always)] pub fn velocity(&self) -> Vec2 { self.velocity } /// Where did the current click/drag originate? /// `None` if no mouse button is down. + #[inline(always)] pub fn press_origin(&self) -> Option { self.press_origin } /// Latest reported pointer position. /// When tapping a touch screen, this will be `None`. + #[inline(always)] pub(crate) fn latest_pos(&self) -> Option { self.latest_pos } /// If it is a good idea to show a tooltip, where is pointer? + #[inline(always)] pub fn hover_pos(&self) -> Option { self.latest_pos } @@ -424,6 +429,7 @@ impl PointerState { /// Latest position of the mouse, but ignoring any [`Event::PointerGone`] /// if there were interactions this frame. /// When tapping a touch screen, this will be the location of the touch. + #[inline(always)] pub fn interact_pos(&self) -> Option { self.interact_pos } @@ -431,12 +437,14 @@ impl PointerState { /// Do we have a pointer? /// /// `false` if the mouse is not over the egui area, or if no touches are down on touch screens. + #[inline(always)] pub fn has_pointer(&self) -> bool { self.latest_pos.is_some() } /// Is the pointer currently still? /// This is smoothed so a few frames of stillness is required before this returns `true`. + #[inline(always)] pub fn is_still(&self) -> bool { self.velocity == Vec2::ZERO } diff --git a/egui/src/layers.rs b/egui/src/layers.rs index 6e2b7bae9..e2e6417ba 100644 --- a/egui/src/layers.rs +++ b/egui/src/layers.rs @@ -34,6 +34,7 @@ impl Order { Self::Debug, ]; + #[inline(always)] pub fn allow_interaction(&self) -> bool { match self { Self::Background | Self::Middle | Self::Foreground | Self::Debug => true, @@ -70,6 +71,7 @@ impl LayerId { } } + #[inline(always)] pub fn allow_interaction(&self) -> bool { self.order.allow_interaction() } @@ -84,11 +86,13 @@ pub struct ShapeIdx(usize); pub struct PaintList(Vec); impl PaintList { + #[inline(always)] pub fn is_empty(&self) -> bool { self.0.is_empty() } /// Returns the index of the new [`Shape`] that can be used with `PaintList::set`. + #[inline(always)] pub fn add(&mut self, clip_rect: Rect, shape: Shape) -> ShapeIdx { let idx = ShapeIdx(self.0.len()); self.0.push(ClippedShape(clip_rect, shape)); @@ -107,8 +111,8 @@ impl PaintList { /// /// The solution is to allocate a `Shape` using `let idx = paint_list.add(cr, Shape::Noop);` /// and then later setting it using `paint_list.set(idx, cr, frame);`. + #[inline(always)] pub fn set(&mut self, idx: ShapeIdx, clip_rect: Rect, shape: Shape) { - assert!(idx.0 < self.0.len()); self.0[idx.0] = ClippedShape(clip_rect, shape); } diff --git a/egui/src/memory.rs b/egui/src/memory.rs index 4377718a0..fd8698f65 100644 --- a/egui/src/memory.rs +++ b/egui/src/memory.rs @@ -299,6 +299,7 @@ impl Memory { self.interaction.focus.id = Some(id); } + #[inline(always)] pub fn surrender_focus(&mut self, id: Id) { if self.interaction.focus.id == Some(id) { self.interaction.focus.id = None; @@ -307,6 +308,7 @@ impl Memory { /// Register this widget as being interested in getting keyboard focus. /// This will allow the user to select it with tab and shift-tab. + #[inline(always)] pub(crate) fn interested_in_focus(&mut self, id: Id) { self.interaction.focus.interested_in_focus(id); } @@ -360,6 +362,7 @@ impl Memory { /// This is useful for testing, benchmarking, pre-caching, etc. /// /// Experimental feature! + #[inline(always)] pub fn everything_is_visible(&self) -> bool { self.everything_is_visible } diff --git a/egui/src/response.rs b/egui/src/response.rs index 73b65c4d9..7fba51351 100644 --- a/egui/src/response.rs +++ b/egui/src/response.rs @@ -104,6 +104,7 @@ impl std::fmt::Debug for Response { impl Response { /// Returns true if this widget was clicked this frame by the primary button. + #[inline(always)] pub fn clicked(&self) -> bool { self.clicked[PointerButton::Primary as usize] } @@ -149,11 +150,13 @@ impl Response { /// Was the widget enabled? /// If false, there was no interaction attempted /// and the widget should be drawn in a gray disabled look. + #[inline(always)] pub fn enabled(&self) -> bool { self.enabled } /// The pointer is hovering above this widget or the widget was clicked/tapped this frame. + #[inline(always)] pub fn hovered(&self) -> bool { self.hovered } @@ -194,6 +197,7 @@ impl Response { /// /// To find out which button(s), query [`crate::PointerState::button_down`] /// (`ui.input().pointer.button_down(…)`). + #[inline(always)] pub fn dragged(&self) -> bool { self.dragged } @@ -239,6 +243,7 @@ impl Response { /// Is the pointer button currently down on this widget? /// This is true if the pointer is pressing down or dragging a widget + #[inline(always)] pub fn is_pointer_button_down_on(&self) -> bool { self.is_pointer_button_down_on } @@ -249,6 +254,7 @@ impl Response { /// Always `false` for something like a `Button`. /// Can sometimes be `true` even though the data didn't changed /// (e.g. if the user entered a character and erased it the same frame). + #[inline(always)] pub fn changed(&self) -> bool { self.changed } @@ -257,6 +263,7 @@ impl Response { /// /// This must be called by widgets that represent some mutable data, /// e.g. checkboxes, sliders etc. + #[inline(always)] pub fn mark_changed(&mut self) { self.changed = true; } diff --git a/egui/src/widgets/plot.rs b/egui/src/widgets/plot.rs index 74ef9da38..4435a54ac 100644 --- a/egui/src/widgets/plot.rs +++ b/egui/src/widgets/plot.rs @@ -22,6 +22,7 @@ pub struct Value { } impl Value { + #[inline(always)] pub fn new(x: impl Into, y: impl Into) -> Self { Self { x: x.into(), diff --git a/egui_demo_lib/benches/benchmark.rs b/egui_demo_lib/benches/benchmark.rs index 3a47c9bfd..30ab8b92f 100644 --- a/egui_demo_lib/benches/benchmark.rs +++ b/egui_demo_lib/benches/benchmark.rs @@ -19,7 +19,7 @@ pub fn criterion_benchmark(c: &mut Criterion) { }) }); - c.bench_function("demo_windows_minimal (no tesselation)", |b| { + c.bench_function("demo_windows_minimal_no_tesselation", |b| { b.iter(|| { ctx.begin_frame(raw_input.clone()); demo_windows.ui(&ctx); diff --git a/epaint/src/text/fonts.rs b/epaint/src/text/fonts.rs index 139028fd4..4ffa08d29 100644 --- a/epaint/src/text/fonts.rs +++ b/epaint/src/text/fonts.rs @@ -1,9 +1,11 @@ use std::{ - collections::{BTreeMap, HashMap}, + collections::BTreeMap, hash::{Hash, Hasher}, sync::Arc, }; +use ahash::AHashMap; + use crate::{ mutex::Mutex, text::{ @@ -390,7 +392,7 @@ struct CachedGalley { struct GalleyCache { /// Frame counter used to do garbage collection on the cache generation: u32, - cache: HashMap, + cache: AHashMap, } impl GalleyCache {