From f5bcfec8211c04c4b05f63d01d52d3e5d2cc123e Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Mon, 1 Apr 2024 11:59:46 +0200 Subject: Use `rustc-hash` for most of our `HashMap` and `HashSet` instances --- core/src/image.rs | 5 +++-- core/src/lib.rs | 2 -- core/src/svg.rs | 5 +++-- futures/Cargo.toml | 1 + futures/src/backend/native/async_std.rs | 3 +-- futures/src/backend/native/smol.rs | 3 +-- futures/src/backend/native/tokio.rs | 3 +-- futures/src/subscription.rs | 4 +++- futures/src/subscription/tracker.rs | 9 ++++----- src/advanced.rs | 6 ++++-- wgpu/Cargo.toml | 1 + wgpu/src/image/raster.rs | 6 +++--- wgpu/src/image/vector.rs | 10 +++++----- wgpu/src/primitive/pipeline.rs | 4 ++-- widget/Cargo.toml | 1 + widget/src/lazy.rs | 21 ++++++++++++++------- widget/src/pane_grid/state.rs | 8 ++++---- winit/Cargo.toml | 1 + winit/src/multi_window.rs | 16 ++++++++-------- 19 files changed, 60 insertions(+), 49 deletions(-) diff --git a/core/src/image.rs b/core/src/image.rs index 32b95f03..dc74e5c1 100644 --- a/core/src/image.rs +++ b/core/src/image.rs @@ -1,6 +1,7 @@ //! Load and draw raster graphics. -use crate::{Hasher, Rectangle, Size}; +use crate::{Rectangle, Size}; +use rustc_hash::FxHasher; use std::hash::{Hash, Hasher as _}; use std::path::PathBuf; use std::sync::Arc; @@ -50,7 +51,7 @@ impl Handle { } fn from_data(data: Data) -> Handle { - let mut hasher = Hasher::default(); + let mut hasher = FxHasher::default(); data.hash(&mut hasher); Handle { diff --git a/core/src/lib.rs b/core/src/lib.rs index d076413e..832b2d2d 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -41,7 +41,6 @@ mod background; mod color; mod content_fit; mod element; -mod hasher; mod length; mod padding; mod pixels; @@ -64,7 +63,6 @@ pub use element::Element; pub use event::Event; pub use font::Font; pub use gradient::Gradient; -pub use hasher::Hasher; pub use layout::Layout; pub use length::Length; pub use overlay::Overlay; diff --git a/core/src/svg.rs b/core/src/svg.rs index ab207cca..0106e0c2 100644 --- a/core/src/svg.rs +++ b/core/src/svg.rs @@ -1,6 +1,7 @@ //! Load and draw vector graphics. -use crate::{Color, Hasher, Rectangle, Size}; +use crate::{Color, Rectangle, Size}; +use rustc_hash::FxHasher; use std::borrow::Cow; use std::hash::{Hash, Hasher as _}; use std::path::PathBuf; @@ -30,7 +31,7 @@ impl Handle { } fn from_data(data: Data) -> Handle { - let mut hasher = Hasher::default(); + let mut hasher = FxHasher::default(); data.hash(&mut hasher); Handle { diff --git a/futures/Cargo.toml b/futures/Cargo.toml index 69a915e4..bbcfe01c 100644 --- a/futures/Cargo.toml +++ b/futures/Cargo.toml @@ -22,6 +22,7 @@ iced_core.workspace = true futures.workspace = true log.workspace = true +rustc-hash.workspace = true [target.'cfg(not(target_arch = "wasm32"))'.dependencies] async-std.workspace = true diff --git a/futures/src/backend/native/async_std.rs b/futures/src/backend/native/async_std.rs index 52b0e914..b7da5e90 100644 --- a/futures/src/backend/native/async_std.rs +++ b/futures/src/backend/native/async_std.rs @@ -18,8 +18,7 @@ impl crate::Executor for Executor { pub mod time { //! Listen and react to time. - use crate::core::Hasher; - use crate::subscription::{self, Subscription}; + use crate::subscription::{self, Hasher, Subscription}; /// Returns a [`Subscription`] that produces messages at a set interval. /// diff --git a/futures/src/backend/native/smol.rs b/futures/src/backend/native/smol.rs index 00d13d35..aaf1518c 100644 --- a/futures/src/backend/native/smol.rs +++ b/futures/src/backend/native/smol.rs @@ -17,8 +17,7 @@ impl crate::Executor for Executor { pub mod time { //! Listen and react to time. - use crate::core::Hasher; - use crate::subscription::{self, Subscription}; + use crate::subscription::{self, Hasher, Subscription}; /// Returns a [`Subscription`] that produces messages at a set interval. /// diff --git a/futures/src/backend/native/tokio.rs b/futures/src/backend/native/tokio.rs index 4698a105..3ab7f675 100644 --- a/futures/src/backend/native/tokio.rs +++ b/futures/src/backend/native/tokio.rs @@ -22,8 +22,7 @@ impl crate::Executor for Executor { pub mod time { //! Listen and react to time. - use crate::core::Hasher; - use crate::subscription::{self, Subscription}; + use crate::subscription::{self, Hasher, Subscription}; /// Returns a [`Subscription`] that produces messages at a set interval. /// diff --git a/futures/src/subscription.rs b/futures/src/subscription.rs index 7537c022..93e35608 100644 --- a/futures/src/subscription.rs +++ b/futures/src/subscription.rs @@ -4,7 +4,6 @@ mod tracker; pub use tracker::Tracker; use crate::core::event::{self, Event}; -use crate::core::Hasher; use crate::futures::{Future, Stream}; use crate::{BoxStream, MaybeSend}; @@ -18,6 +17,9 @@ use std::hash::Hash; /// It is the input of a [`Subscription`]. pub type EventStream = BoxStream<(Event, event::Status)>; +/// The hasher used for identifying subscriptions. +pub type Hasher = rustc_hash::FxHasher; + /// A request to listen to external events. /// /// Besides performing async actions on demand with `Command`, most diff --git a/futures/src/subscription/tracker.rs b/futures/src/subscription/tracker.rs index 15ed5b87..277a446b 100644 --- a/futures/src/subscription/tracker.rs +++ b/futures/src/subscription/tracker.rs @@ -1,12 +1,11 @@ use crate::core::event::{self, Event}; -use crate::core::Hasher; -use crate::subscription::Recipe; +use crate::subscription::{Hasher, Recipe}; use crate::{BoxFuture, MaybeSend}; use futures::channel::mpsc; use futures::sink::{Sink, SinkExt}; +use rustc_hash::FxHashMap; -use std::collections::HashMap; use std::hash::Hasher as _; /// A registry of subscription streams. @@ -18,7 +17,7 @@ use std::hash::Hasher as _; /// [`Subscription`]: crate::Subscription #[derive(Debug, Default)] pub struct Tracker { - subscriptions: HashMap, + subscriptions: FxHashMap, } #[derive(Debug)] @@ -31,7 +30,7 @@ impl Tracker { /// Creates a new empty [`Tracker`]. pub fn new() -> Self { Self { - subscriptions: HashMap::new(), + subscriptions: FxHashMap::default(), } } diff --git a/src/advanced.rs b/src/advanced.rs index 306c3559..5826ba0f 100644 --- a/src/advanced.rs +++ b/src/advanced.rs @@ -9,10 +9,12 @@ pub use crate::core::renderer::{self, Renderer}; pub use crate::core::svg; pub use crate::core::text::{self, Text}; pub use crate::core::widget::{self, Widget}; -pub use crate::core::{Hasher, Shell}; +pub use crate::core::Shell; pub use crate::renderer::graphics; pub mod subscription { //! Write your own subscriptions. - pub use crate::runtime::futures::subscription::{EventStream, Recipe}; + pub use crate::runtime::futures::subscription::{ + EventStream, Hasher, Recipe, + }; } diff --git a/wgpu/Cargo.toml b/wgpu/Cargo.toml index f6162e0f..0b713784 100644 --- a/wgpu/Cargo.toml +++ b/wgpu/Cargo.toml @@ -32,6 +32,7 @@ glyphon.workspace = true guillotiere.workspace = true log.workspace = true once_cell.workspace = true +rustc-hash.workspace = true thiserror.workspace = true wgpu.workspace = true diff --git a/wgpu/src/image/raster.rs b/wgpu/src/image/raster.rs index a6cba76a..441b294f 100644 --- a/wgpu/src/image/raster.rs +++ b/wgpu/src/image/raster.rs @@ -4,7 +4,7 @@ use crate::graphics; use crate::graphics::image::image_rs; use crate::image::atlas::{self, Atlas}; -use std::collections::{HashMap, HashSet}; +use rustc_hash::{FxHashMap, FxHashSet}; /// Entry in cache corresponding to an image handle #[derive(Debug)] @@ -38,8 +38,8 @@ impl Memory { /// Caches image raster data #[derive(Debug, Default)] pub struct Cache { - map: HashMap, - hits: HashSet, + map: FxHashMap, + hits: FxHashSet, } impl Cache { diff --git a/wgpu/src/image/vector.rs b/wgpu/src/image/vector.rs index d9be50d7..d681b2e6 100644 --- a/wgpu/src/image/vector.rs +++ b/wgpu/src/image/vector.rs @@ -5,7 +5,7 @@ use crate::image::atlas::{self, Atlas}; use resvg::tiny_skia; use resvg::usvg::{self, TreeTextToPath}; -use std::collections::{HashMap, HashSet}; +use rustc_hash::{FxHashMap, FxHashSet}; use std::fs; /// Entry in cache corresponding to an svg handle @@ -33,10 +33,10 @@ impl Svg { /// Caches svg vector and raster data #[derive(Debug, Default)] pub struct Cache { - svgs: HashMap, - rasterized: HashMap<(u64, u32, u32, ColorFilter), atlas::Entry>, - svg_hits: HashSet, - rasterized_hits: HashSet<(u64, u32, u32, ColorFilter)>, + svgs: FxHashMap, + rasterized: FxHashMap<(u64, u32, u32, ColorFilter), atlas::Entry>, + svg_hits: FxHashSet, + rasterized_hits: FxHashSet<(u64, u32, u32, ColorFilter)>, } type ColorFilter = Option<[u8; 4]>; diff --git a/wgpu/src/primitive/pipeline.rs b/wgpu/src/primitive/pipeline.rs index 814440ba..59c54db9 100644 --- a/wgpu/src/primitive/pipeline.rs +++ b/wgpu/src/primitive/pipeline.rs @@ -1,8 +1,8 @@ //! Draw primitives using custom pipelines. use crate::core::{self, Rectangle, Size}; +use rustc_hash::FxHashMap; use std::any::{Any, TypeId}; -use std::collections::HashMap; use std::fmt::Debug; use std::sync::Arc; @@ -82,7 +82,7 @@ impl Renderer for crate::Renderer { /// Stores custom, user-provided pipelines. #[derive(Default, Debug)] pub struct Storage { - pipelines: HashMap>, + pipelines: FxHashMap>, } impl Storage { diff --git a/widget/Cargo.toml b/widget/Cargo.toml index a45f47ef..84525935 100644 --- a/widget/Cargo.toml +++ b/widget/Cargo.toml @@ -28,6 +28,7 @@ iced_renderer.workspace = true iced_runtime.workspace = true num-traits.workspace = true +rustc-hash.workspace = true thiserror.workspace = true unicode-segmentation.workspace = true diff --git a/widget/src/lazy.rs b/widget/src/lazy.rs index eb663ea5..04783dbe 100644 --- a/widget/src/lazy.rs +++ b/widget/src/lazy.rs @@ -18,11 +18,12 @@ use crate::core::widget::tree::{self, Tree}; use crate::core::widget::{self, Widget}; use crate::core::Element; use crate::core::{ - self, Clipboard, Hasher, Length, Point, Rectangle, Shell, Size, Vector, + self, Clipboard, Length, Point, Rectangle, Shell, Size, Vector, }; use crate::runtime::overlay::Nested; use ouroboros::self_referencing; +use rustc_hash::FxHasher; use std::cell::RefCell; use std::hash::{Hash, Hasher as H}; use std::rc::Rc; @@ -106,9 +107,12 @@ where } fn state(&self) -> tree::State { - let mut hasher = Hasher::default(); - self.dependency.hash(&mut hasher); - let hash = hasher.finish(); + let hash = { + let mut hasher = FxHasher::default(); + self.dependency.hash(&mut hasher); + + hasher.finish() + }; let element = Rc::new(RefCell::new(Some((self.view)(&self.dependency).into()))); @@ -127,9 +131,12 @@ where .state .downcast_mut::>(); - let mut hasher = Hasher::default(); - self.dependency.hash(&mut hasher); - let new_hash = hasher.finish(); + let new_hash = { + let mut hasher = FxHasher::default(); + self.dependency.hash(&mut hasher); + + hasher.finish() + }; if current.hash != new_hash { current.hash = new_hash; diff --git a/widget/src/pane_grid/state.rs b/widget/src/pane_grid/state.rs index 481cd770..c20c3b9c 100644 --- a/widget/src/pane_grid/state.rs +++ b/widget/src/pane_grid/state.rs @@ -6,7 +6,7 @@ use crate::pane_grid::{ Axis, Configuration, Direction, Edge, Node, Pane, Region, Split, Target, }; -use std::collections::HashMap; +use rustc_hash::FxHashMap; /// The state of a [`PaneGrid`]. /// @@ -25,7 +25,7 @@ pub struct State { /// The panes of the [`PaneGrid`]. /// /// [`PaneGrid`]: super::PaneGrid - pub panes: HashMap, + pub panes: FxHashMap, /// The internal state of the [`PaneGrid`]. /// @@ -52,7 +52,7 @@ impl State { /// Creates a new [`State`] with the given [`Configuration`]. pub fn with_configuration(config: impl Into>) -> Self { - let mut panes = HashMap::new(); + let mut panes = FxHashMap::default(); let internal = Internal::from_configuration(&mut panes, config.into(), 0); @@ -353,7 +353,7 @@ impl Internal { /// /// [`PaneGrid`]: super::PaneGrid pub fn from_configuration( - panes: &mut HashMap, + panes: &mut FxHashMap, content: Configuration, next_id: usize, ) -> Self { diff --git a/winit/Cargo.toml b/winit/Cargo.toml index 9d65cc1b..29e744b2 100644 --- a/winit/Cargo.toml +++ b/winit/Cargo.toml @@ -26,6 +26,7 @@ iced_graphics.workspace = true iced_runtime.workspace = true log.workspace = true +rustc-hash.workspace = true thiserror.workspace = true tracing.workspace = true window_clipboard.workspace = true diff --git a/winit/src/multi_window.rs b/winit/src/multi_window.rs index b4c25411..e17cc180 100644 --- a/winit/src/multi_window.rs +++ b/winit/src/multi_window.rs @@ -27,7 +27,7 @@ use crate::{Clipboard, Error, Proxy, Settings}; pub use crate::application::{default, Appearance, DefaultStyle}; -use std::collections::HashMap; +use rustc_hash::FxHashMap; use std::mem::ManuallyDrop; use std::sync::Arc; use std::time::Instant; @@ -381,12 +381,12 @@ async fn run_instance( )] }; - let mut ui_caches = HashMap::new(); + let mut ui_caches = FxHashMap::default(); let mut user_interfaces = ManuallyDrop::new(build_user_interfaces( &application, &mut debug, &mut window_manager, - HashMap::from_iter([( + FxHashMap::from_iter([( window::Id::MAIN, user_interface::Cache::default(), )]), @@ -759,7 +759,7 @@ async fn run_instance( // TODO mw application update returns which window IDs to update if !messages.is_empty() || uis_stale { - let mut cached_interfaces: HashMap< + let mut cached_interfaces: FxHashMap< window::Id, user_interface::Cache, > = ManuallyDrop::into_inner(user_interfaces) @@ -849,7 +849,7 @@ fn update( debug: &mut Debug, messages: &mut Vec, window_manager: &mut WindowManager, - ui_caches: &mut HashMap, + ui_caches: &mut FxHashMap, ) where C: Compositor + 'static, A::Theme: DefaultStyle, @@ -890,7 +890,7 @@ fn run_command( proxy: &mut winit::event_loop::EventLoopProxy, debug: &mut Debug, window_manager: &mut WindowManager, - ui_caches: &mut HashMap, + ui_caches: &mut FxHashMap, ) where A: Application, E: Executor, @@ -1218,8 +1218,8 @@ pub fn build_user_interfaces<'a, A: Application, C: Compositor>( application: &'a A, debug: &mut Debug, window_manager: &mut WindowManager, - mut cached_user_interfaces: HashMap, -) -> HashMap> + mut cached_user_interfaces: FxHashMap, +) -> FxHashMap> where C: Compositor, A::Theme: DefaultStyle, -- cgit