From d59fdc1eb6fa162f48aa998b859230795a26f089 Mon Sep 17 00:00:00 2001 From: Joseph Perez Date: Wed, 15 Jan 2025 17:54:36 +0100 Subject: [PATCH] refactor: use foldhash in critical path Performance of both publisher and subscribers are improved significantly. --- Cargo.lock | 7 +++++++ Cargo.toml | 1 + zenoh/Cargo.toml | 1 + zenoh/src/api/session.rs | 9 +++++---- zenoh/src/net/routing/dispatcher/face.rs | 9 +++++---- zenoh/src/net/routing/dispatcher/resource.rs | 13 +++++++------ 6 files changed, 26 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 69148b230b..df3d70546d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1368,6 +1368,12 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foldhash" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f" + [[package]] name = "form_urlencoded" version = "1.2.1" @@ -5081,6 +5087,7 @@ dependencies = [ "async-trait", "bytes", "flume", + "foldhash", "futures", "git-version", "itertools 0.13.0", diff --git a/Cargo.toml b/Cargo.toml index f2b96a40be..f8ed478398 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -98,6 +98,7 @@ derive-new = "0.7.0" tracing-subscriber = { version = "0.3", features = ["json", "env-filter"] } event-listener = "5.3.1" flume = "0.11" +foldhash = { version = "0.1.4", default-features = false } form_urlencoded = "1.2.1" futures = "0.3.30" futures-util = { version = "0.3.30", default-features = false } # Default features are disabled due to some crates' requirements diff --git a/zenoh/Cargo.toml b/zenoh/Cargo.toml index 1359bdd1b1..fe246712b3 100644 --- a/zenoh/Cargo.toml +++ b/zenoh/Cargo.toml @@ -74,6 +74,7 @@ ahash = { workspace = true } async-trait = { workspace = true } bytes = { workspace = true } flume = { workspace = true } +foldhash = { workspace = true, features = ["default"] } futures = { workspace = true } git-version = { workspace = true } itertools = { workspace = true } diff --git a/zenoh/src/api/session.rs b/zenoh/src/api/session.rs index 907ef70651..ab0c5f11c9 100644 --- a/zenoh/src/api/session.rs +++ b/zenoh/src/api/session.rs @@ -24,6 +24,7 @@ use std::{ }; use async_trait::async_trait; +use foldhash::HashMapExt; #[zenoh_macros::internal] use ref_cast::ref_cast_custom; use ref_cast::RefCastCustom; @@ -129,8 +130,8 @@ pub(crate) struct SessionState { pub(crate) expr_id_counter: AtomicExprId, // @TODO: manage rollover and uniqueness pub(crate) qid_counter: AtomicRequestId, pub(crate) liveliness_qid_counter: AtomicRequestId, - pub(crate) local_resources: HashMap, - pub(crate) remote_resources: HashMap, + pub(crate) local_resources: foldhash::HashMap, + pub(crate) remote_resources: foldhash::HashMap, #[cfg(feature = "unstable")] pub(crate) remote_subscribers: HashMap>, pub(crate) publishers: HashMap, @@ -163,8 +164,8 @@ impl SessionState { expr_id_counter: AtomicExprId::new(1), // Note: start at 1 because 0 is reserved for NO_RESOURCE qid_counter: AtomicRequestId::new(0), liveliness_qid_counter: AtomicRequestId::new(0), - local_resources: HashMap::new(), - remote_resources: HashMap::new(), + local_resources: foldhash::HashMap::new(), + remote_resources: foldhash::HashMap::new(), #[cfg(feature = "unstable")] remote_subscribers: HashMap::new(), publishers: HashMap::new(), diff --git a/zenoh/src/net/routing/dispatcher/face.rs b/zenoh/src/net/routing/dispatcher/face.rs index fd6c85ff2c..d0cd064264 100644 --- a/zenoh/src/net/routing/dispatcher/face.rs +++ b/zenoh/src/net/routing/dispatcher/face.rs @@ -19,6 +19,7 @@ use std::{ time::Duration, }; +use foldhash::HashMapExt; use tokio_util::sync::CancellationToken; use zenoh_protocol::{ core::{ExprId, Reliability, WhatAmI, WireExpr, ZenohIdProto}, @@ -68,8 +69,8 @@ pub struct FaceState { pub(crate) remote_key_interests: HashMap>>, pub(crate) pending_current_interests: HashMap, CancellationToken)>, - pub(crate) local_mappings: HashMap>, - pub(crate) remote_mappings: HashMap>, + pub(crate) local_mappings: foldhash::HashMap>, + pub(crate) remote_mappings: foldhash::HashMap>, pub(crate) next_qid: RequestId, pub(crate) pending_queries: HashMap, CancellationToken)>, pub(crate) mcast_group: Option, @@ -100,8 +101,8 @@ impl FaceState { local_interests: HashMap::new(), remote_key_interests: HashMap::new(), pending_current_interests: HashMap::new(), - local_mappings: HashMap::new(), - remote_mappings: HashMap::new(), + local_mappings: foldhash::HashMap::new(), + remote_mappings: foldhash::HashMap::new(), next_qid: 0, pending_queries: HashMap::new(), mcast_group, diff --git a/zenoh/src/net/routing/dispatcher/resource.rs b/zenoh/src/net/routing/dispatcher/resource.rs index 58e1459ece..efaa768b08 100644 --- a/zenoh/src/net/routing/dispatcher/resource.rs +++ b/zenoh/src/net/routing/dispatcher/resource.rs @@ -19,6 +19,7 @@ use std::{ sync::{Arc, Weak}, }; +use foldhash::HashMapExt; use zenoh_config::WhatAmI; use zenoh_protocol::{ core::{key_expr::keyexpr, ExprId, WireExpr}, @@ -168,9 +169,9 @@ pub struct Resource { pub(crate) expr: String, pub(crate) suffix: String, pub(crate) nonwild_prefix: Option<(Arc, String)>, - pub(crate) children: HashMap>, + pub(crate) children: foldhash::HashMap>, pub(crate) context: Option, - pub(crate) session_ctxs: HashMap>, + pub(crate) session_ctxs: foldhash::HashMap>, } impl PartialEq for Resource { @@ -208,9 +209,9 @@ impl Resource { expr: parent.expr.clone() + suffix, suffix: String::from(suffix), nonwild_prefix, - children: HashMap::new(), + children: foldhash::HashMap::new(), context, - session_ctxs: HashMap::new(), + session_ctxs: foldhash::HashMap::new(), } } @@ -298,9 +299,9 @@ impl Resource { expr: String::from(""), suffix: String::from(""), nonwild_prefix: None, - children: HashMap::new(), + children: foldhash::HashMap::new(), context: None, - session_ctxs: HashMap::new(), + session_ctxs: foldhash::HashMap::new(), }) }