From e20bdcd8a487b45259deb08b5533fdeb63554231 Mon Sep 17 00:00:00 2001 From: Benjamin Bouvier Date: Wed, 3 Sep 2025 14:17:51 +0200 Subject: [PATCH 1/2] perf: precompute the room notification modes if and only if push rules have changed The room notification modes will only change when the push rules have changed; otherwise, recomputing them is a no-op, and only wastes time. Here's a distribution of the worst processing times under this method, as measured in multiverse with my personal account running (fresh, i.e. after an initial response) for a few minutes: Before: 0.001358279s 0.019668889s 0.030104444s 0.030376296s 0.048609819s 0.049683619s 0.054289813s 0.063690030s After: 0.000000385s 0.000000387s 0.000000410s 0.000000430s 0.000000438s 0.000000478s 0.000000487s 0.000000568s 0.010011267s The new distribution makes sense: the push rules event comes only once, in the initial response, so they're processed only once. Then, there's no need to process it ever again (in my session I've never changed the processing times), so it's almost instantaneous the subsequent times. --- crates/matrix-sdk/src/sliding_sync/client.rs | 35 ++++++++++++++------ 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/crates/matrix-sdk/src/sliding_sync/client.rs b/crates/matrix-sdk/src/sliding_sync/client.rs index 0d4c46704c9..2450f656656 100644 --- a/crates/matrix-sdk/src/sliding_sync/client.rs +++ b/crates/matrix-sdk/src/sliding_sync/client.rs @@ -4,9 +4,12 @@ use matrix_sdk_base::{ sync::SyncResponse, timer, RequestedRequiredStates, ThreadSubscriptionCatchupToken, }; use matrix_sdk_common::deserialized_responses::ProcessedToDeviceEvent; -use ruma::api::{ - client::sync::sync_events::v5::{self as http, response}, - FeatureFlag, SupportedVersions, +use ruma::{ + api::{ + client::sync::sync_events::v5::{self as http, response}, + FeatureFlag, SupportedVersions, + }, + events::GlobalAccountDataEventType, }; use tracing::error; @@ -242,13 +245,25 @@ impl SlidingSyncResponseProcessor { async fn update_in_memory_caches(client: &Client, response: &SyncResponse) -> Result<()> { let _timer = timer!(tracing::Level::TRACE, "update_in_memory_caches"); - for room_id in response.rooms.joined.keys() { - let Some(room) = client.get_room(room_id) else { - error!(?room_id, "Cannot post process a room in sliding sync because it is missing"); - continue; - }; - - room.user_defined_notification_mode().await; + // Only update the notification modes if the push rules have changed. + if response.account_data.iter().any(|event| { + event + .get_field::("type") + .ok() + .flatten() + .map_or(false, |event_type| event_type == GlobalAccountDataEventType::PushRules) + }) { + for room_id in response.rooms.joined.keys() { + let Some(room) = client.get_room(room_id) else { + error!( + ?room_id, + "Cannot post process a room in sliding sync because it is missing" + ); + continue; + }; + + room.user_defined_notification_mode().await; + } } Ok(()) From 5ea16b9725b2ce4861a3adcac6e0010d8c7ac4fd Mon Sep 17 00:00:00 2001 From: Benjamin Bouvier Date: Wed, 3 Sep 2025 14:34:31 +0200 Subject: [PATCH 2/2] fixup! perf: precompute the room notification modes if and only if push rules have changed --- crates/matrix-sdk/src/sliding_sync/client.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/matrix-sdk/src/sliding_sync/client.rs b/crates/matrix-sdk/src/sliding_sync/client.rs index 2450f656656..36122312732 100644 --- a/crates/matrix-sdk/src/sliding_sync/client.rs +++ b/crates/matrix-sdk/src/sliding_sync/client.rs @@ -251,7 +251,7 @@ async fn update_in_memory_caches(client: &Client, response: &SyncResponse) -> Re .get_field::("type") .ok() .flatten() - .map_or(false, |event_type| event_type == GlobalAccountDataEventType::PushRules) + .is_some_and(|event_type| event_type == GlobalAccountDataEventType::PushRules) }) { for room_id in response.rooms.joined.keys() { let Some(room) = client.get_room(room_id) else {