From 15ab77629f54242ab60336e81976d36efa0cf2b8 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Wed, 10 Jan 2024 13:22:51 +0100 Subject: [PATCH] feat(base): Make `Store::get_rooms` wayyy faster. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `Store::get_rooms` worked as follows: For each room ID, call * Take the read lock for `rooms`, * For each entry in `rooms`, take the room ID (the key), then call `Store::get_room`, which… * Take the read lock for `rooms`, * Based on the room ID (the key), read the room (the value) from `rooms`. So calling `get_rooms` calls `get_room` for each room, which takes the lock every time. This patch modifies that by fetching the values (the rooms) directly from `rooms`, without calling `get_room`. In my benchmark, it took 1.2ms to read 10'000 rooms. Now it takes 542µs. Performance time has improved by -55.8%. --- crates/matrix-sdk-base/src/store/mod.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/matrix-sdk-base/src/store/mod.rs b/crates/matrix-sdk-base/src/store/mod.rs index 920c78995ef..f2784caa8d7 100644 --- a/crates/matrix-sdk-base/src/store/mod.rs +++ b/crates/matrix-sdk-base/src/store/mod.rs @@ -142,6 +142,7 @@ pub(crate) struct Store { session_meta: Arc>, /// The current sync token that should be used for the next sync call. pub(super) sync_token: Arc>>, + /// All rooms the store knows about. rooms: Arc>>, /// A lock to synchronize access to the store, such that data by the sync is /// never overwritten. @@ -203,7 +204,7 @@ impl Store { /// Get all the rooms this store knows about. pub fn get_rooms(&self) -> Vec { - self.rooms.read().unwrap().keys().filter_map(|id| self.get_room(id)).collect() + self.rooms.read().unwrap().values().cloned().collect() } /// Get all the rooms this store knows about, filtered by state.