Optimize: more inlining and more use of AHashMap

No real gains, but it didn't hurt either
This commit is contained in:
Emil Ernerfeldt 2021-03-31 17:06:12 +02:00
parent 4984d51f99
commit 4808da44a2
9 changed files with 32 additions and 6 deletions

View file

@ -1,10 +1,10 @@
use std::collections::HashMap; use epaint::ahash::AHashMap;
use crate::{emath::remap_clamp, Id, InputState}; use crate::{emath::remap_clamp, Id, InputState};
#[derive(Clone, Default)] #[derive(Clone, Default)]
pub(crate) struct AnimationManager { pub(crate) struct AnimationManager {
bools: HashMap<Id, BoolAnim>, bools: AHashMap<Id, BoolAnim>,
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug)]

View file

@ -385,6 +385,7 @@ impl Context {
self.repaint_requests.store(times_to_repaint, SeqCst); self.repaint_requests.store(times_to_repaint, SeqCst);
} }
#[inline(always)]
pub fn input(&self) -> &InputState { pub fn input(&self) -> &InputState {
&self.input &self.input
} }

View file

@ -393,28 +393,33 @@ impl PointerState {
} }
/// How much the pointer moved compared to last frame, in points. /// How much the pointer moved compared to last frame, in points.
#[inline(always)]
pub fn delta(&self) -> Vec2 { pub fn delta(&self) -> Vec2 {
self.delta self.delta
} }
/// Current velocity of pointer. /// Current velocity of pointer.
#[inline(always)]
pub fn velocity(&self) -> Vec2 { pub fn velocity(&self) -> Vec2 {
self.velocity self.velocity
} }
/// Where did the current click/drag originate? /// Where did the current click/drag originate?
/// `None` if no mouse button is down. /// `None` if no mouse button is down.
#[inline(always)]
pub fn press_origin(&self) -> Option<Pos2> { pub fn press_origin(&self) -> Option<Pos2> {
self.press_origin self.press_origin
} }
/// Latest reported pointer position. /// Latest reported pointer position.
/// When tapping a touch screen, this will be `None`. /// When tapping a touch screen, this will be `None`.
#[inline(always)]
pub(crate) fn latest_pos(&self) -> Option<Pos2> { pub(crate) fn latest_pos(&self) -> Option<Pos2> {
self.latest_pos self.latest_pos
} }
/// If it is a good idea to show a tooltip, where is pointer? /// If it is a good idea to show a tooltip, where is pointer?
#[inline(always)]
pub fn hover_pos(&self) -> Option<Pos2> { pub fn hover_pos(&self) -> Option<Pos2> {
self.latest_pos self.latest_pos
} }
@ -424,6 +429,7 @@ impl PointerState {
/// Latest position of the mouse, but ignoring any [`Event::PointerGone`] /// Latest position of the mouse, but ignoring any [`Event::PointerGone`]
/// if there were interactions this frame. /// if there were interactions this frame.
/// When tapping a touch screen, this will be the location of the touch. /// When tapping a touch screen, this will be the location of the touch.
#[inline(always)]
pub fn interact_pos(&self) -> Option<Pos2> { pub fn interact_pos(&self) -> Option<Pos2> {
self.interact_pos self.interact_pos
} }
@ -431,12 +437,14 @@ impl PointerState {
/// Do we have a pointer? /// Do we have a pointer?
/// ///
/// `false` if the mouse is not over the egui area, or if no touches are down on touch screens. /// `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 { pub fn has_pointer(&self) -> bool {
self.latest_pos.is_some() self.latest_pos.is_some()
} }
/// Is the pointer currently still? /// Is the pointer currently still?
/// This is smoothed so a few frames of stillness is required before this returns `true`. /// This is smoothed so a few frames of stillness is required before this returns `true`.
#[inline(always)]
pub fn is_still(&self) -> bool { pub fn is_still(&self) -> bool {
self.velocity == Vec2::ZERO self.velocity == Vec2::ZERO
} }

View file

@ -34,6 +34,7 @@ impl Order {
Self::Debug, Self::Debug,
]; ];
#[inline(always)]
pub fn allow_interaction(&self) -> bool { pub fn allow_interaction(&self) -> bool {
match self { match self {
Self::Background | Self::Middle | Self::Foreground | Self::Debug => true, Self::Background | Self::Middle | Self::Foreground | Self::Debug => true,
@ -70,6 +71,7 @@ impl LayerId {
} }
} }
#[inline(always)]
pub fn allow_interaction(&self) -> bool { pub fn allow_interaction(&self) -> bool {
self.order.allow_interaction() self.order.allow_interaction()
} }
@ -84,11 +86,13 @@ pub struct ShapeIdx(usize);
pub struct PaintList(Vec<ClippedShape>); pub struct PaintList(Vec<ClippedShape>);
impl PaintList { impl PaintList {
#[inline(always)]
pub fn is_empty(&self) -> bool { pub fn is_empty(&self) -> bool {
self.0.is_empty() self.0.is_empty()
} }
/// Returns the index of the new [`Shape`] that can be used with `PaintList::set`. /// 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 { pub fn add(&mut self, clip_rect: Rect, shape: Shape) -> ShapeIdx {
let idx = ShapeIdx(self.0.len()); let idx = ShapeIdx(self.0.len());
self.0.push(ClippedShape(clip_rect, shape)); 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);` /// 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);`. /// 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) { 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); self.0[idx.0] = ClippedShape(clip_rect, shape);
} }

View file

@ -299,6 +299,7 @@ impl Memory {
self.interaction.focus.id = Some(id); self.interaction.focus.id = Some(id);
} }
#[inline(always)]
pub fn surrender_focus(&mut self, id: Id) { pub fn surrender_focus(&mut self, id: Id) {
if self.interaction.focus.id == Some(id) { if self.interaction.focus.id == Some(id) {
self.interaction.focus.id = None; self.interaction.focus.id = None;
@ -307,6 +308,7 @@ impl Memory {
/// Register this widget as being interested in getting keyboard focus. /// Register this widget as being interested in getting keyboard focus.
/// This will allow the user to select it with tab and shift-tab. /// 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) { pub(crate) fn interested_in_focus(&mut self, id: Id) {
self.interaction.focus.interested_in_focus(id); self.interaction.focus.interested_in_focus(id);
} }
@ -360,6 +362,7 @@ impl Memory {
/// This is useful for testing, benchmarking, pre-caching, etc. /// This is useful for testing, benchmarking, pre-caching, etc.
/// ///
/// Experimental feature! /// Experimental feature!
#[inline(always)]
pub fn everything_is_visible(&self) -> bool { pub fn everything_is_visible(&self) -> bool {
self.everything_is_visible self.everything_is_visible
} }

View file

@ -104,6 +104,7 @@ impl std::fmt::Debug for Response {
impl Response { impl Response {
/// Returns true if this widget was clicked this frame by the primary button. /// Returns true if this widget was clicked this frame by the primary button.
#[inline(always)]
pub fn clicked(&self) -> bool { pub fn clicked(&self) -> bool {
self.clicked[PointerButton::Primary as usize] self.clicked[PointerButton::Primary as usize]
} }
@ -149,11 +150,13 @@ impl Response {
/// Was the widget enabled? /// Was the widget enabled?
/// If false, there was no interaction attempted /// If false, there was no interaction attempted
/// and the widget should be drawn in a gray disabled look. /// and the widget should be drawn in a gray disabled look.
#[inline(always)]
pub fn enabled(&self) -> bool { pub fn enabled(&self) -> bool {
self.enabled self.enabled
} }
/// The pointer is hovering above this widget or the widget was clicked/tapped this frame. /// The pointer is hovering above this widget or the widget was clicked/tapped this frame.
#[inline(always)]
pub fn hovered(&self) -> bool { pub fn hovered(&self) -> bool {
self.hovered self.hovered
} }
@ -194,6 +197,7 @@ impl Response {
/// ///
/// To find out which button(s), query [`crate::PointerState::button_down`] /// To find out which button(s), query [`crate::PointerState::button_down`]
/// (`ui.input().pointer.button_down(…)`). /// (`ui.input().pointer.button_down(…)`).
#[inline(always)]
pub fn dragged(&self) -> bool { pub fn dragged(&self) -> bool {
self.dragged self.dragged
} }
@ -239,6 +243,7 @@ impl Response {
/// Is the pointer button currently down on this widget? /// Is the pointer button currently down on this widget?
/// This is true if the pointer is pressing down or dragging a 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 { pub fn is_pointer_button_down_on(&self) -> bool {
self.is_pointer_button_down_on self.is_pointer_button_down_on
} }
@ -249,6 +254,7 @@ impl Response {
/// Always `false` for something like a `Button`. /// Always `false` for something like a `Button`.
/// Can sometimes be `true` even though the data didn't changed /// 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). /// (e.g. if the user entered a character and erased it the same frame).
#[inline(always)]
pub fn changed(&self) -> bool { pub fn changed(&self) -> bool {
self.changed self.changed
} }
@ -257,6 +263,7 @@ impl Response {
/// ///
/// This must be called by widgets that represent some mutable data, /// This must be called by widgets that represent some mutable data,
/// e.g. checkboxes, sliders etc. /// e.g. checkboxes, sliders etc.
#[inline(always)]
pub fn mark_changed(&mut self) { pub fn mark_changed(&mut self) {
self.changed = true; self.changed = true;
} }

View file

@ -22,6 +22,7 @@ pub struct Value {
} }
impl Value { impl Value {
#[inline(always)]
pub fn new(x: impl Into<f64>, y: impl Into<f64>) -> Self { pub fn new(x: impl Into<f64>, y: impl Into<f64>) -> Self {
Self { Self {
x: x.into(), x: x.into(),

View file

@ -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(|| { b.iter(|| {
ctx.begin_frame(raw_input.clone()); ctx.begin_frame(raw_input.clone());
demo_windows.ui(&ctx); demo_windows.ui(&ctx);

View file

@ -1,9 +1,11 @@
use std::{ use std::{
collections::{BTreeMap, HashMap}, collections::BTreeMap,
hash::{Hash, Hasher}, hash::{Hash, Hasher},
sync::Arc, sync::Arc,
}; };
use ahash::AHashMap;
use crate::{ use crate::{
mutex::Mutex, mutex::Mutex,
text::{ text::{
@ -390,7 +392,7 @@ struct CachedGalley {
struct GalleyCache { struct GalleyCache {
/// Frame counter used to do garbage collection on the cache /// Frame counter used to do garbage collection on the cache
generation: u32, generation: u32,
cache: HashMap<LayoutJob, CachedGalley>, cache: AHashMap<LayoutJob, CachedGalley>,
} }
impl GalleyCache { impl GalleyCache {