From a708e1afd0458120cd0a70609b7254ebd634da03 Mon Sep 17 00:00:00 2001
From: Erik Johnston <erikj@element.io>
Date: Fri, 6 Sep 2024 11:44:13 +0100
Subject: [PATCH] Small performance improvements for sliding sync (#17672)

A couple of small performance improvements for sliding sync.
---
 changelog.d/17672.misc                        |  1 +
 synapse/handlers/sliding_sync/room_lists.py   | 15 ++++++++++-----
 synapse/types/handlers/sliding_sync.py        |  8 +++++++-
 .../client/sliding_sync/test_rooms_meta.py    | 19 ++++++++-----------
 4 files changed, 26 insertions(+), 17 deletions(-)
 create mode 100644 changelog.d/17672.misc

diff --git a/changelog.d/17672.misc b/changelog.d/17672.misc
new file mode 100644
index 0000000000..3550679247
--- /dev/null
+++ b/changelog.d/17672.misc
@@ -0,0 +1 @@
+Small performance improvement in speeding up sliding sync.
diff --git a/synapse/handlers/sliding_sync/room_lists.py b/synapse/handlers/sliding_sync/room_lists.py
index 8d6d8be44f..165b15c60f 100644
--- a/synapse/handlers/sliding_sync/room_lists.py
+++ b/synapse/handlers/sliding_sync/room_lists.py
@@ -350,13 +350,18 @@ class SlidingSyncRoomLists:
 
                     all_rooms.update(filtered_sync_room_map)
 
-                    # Sort the list
-                    sorted_room_info = await self.sort_rooms_using_tables(
-                        filtered_sync_room_map, to_token
-                    )
-
                     ops: List[SlidingSyncResult.SlidingWindowList.Operation] = []
+
                     if list_config.ranges:
+                        if list_config.ranges == [(0, len(filtered_sync_room_map) - 1)]:
+                            # If we are asking for the full range, we don't need to sort the list.
+                            sorted_room_info = list(filtered_sync_room_map.values())
+                        else:
+                            # Sort the list
+                            sorted_room_info = await self.sort_rooms_using_tables(
+                                filtered_sync_room_map, to_token
+                            )
+
                         for range in list_config.ranges:
                             room_ids_in_list: List[str] = []
 
diff --git a/synapse/types/handlers/sliding_sync.py b/synapse/types/handlers/sliding_sync.py
index 84a88bf784..9d934dd563 100644
--- a/synapse/types/handlers/sliding_sync.py
+++ b/synapse/types/handlers/sliding_sync.py
@@ -19,6 +19,7 @@ from enum import Enum
 from typing import (
     TYPE_CHECKING,
     AbstractSet,
+    Any,
     Callable,
     Dict,
     Final,
@@ -703,7 +704,12 @@ class HaveSentRoom(Generic[T]):
 
     @staticmethod
     def never() -> "HaveSentRoom[T]":
-        return HaveSentRoom(HaveSentRoomFlag.NEVER, None)
+        # We use a singleton to avoid repeatedly instantiating new `never`
+        # values.
+        return _HAVE_SENT_ROOM_NEVER
+
+
+_HAVE_SENT_ROOM_NEVER: HaveSentRoom[Any] = HaveSentRoom(HaveSentRoomFlag.NEVER, None)
 
 
 @attr.s(auto_attribs=True, slots=True, frozen=True)
diff --git a/tests/rest/client/sliding_sync/test_rooms_meta.py b/tests/rest/client/sliding_sync/test_rooms_meta.py
index 4ed49040c1..8ce5e8995e 100644
--- a/tests/rest/client/sliding_sync/test_rooms_meta.py
+++ b/tests/rest/client/sliding_sync/test_rooms_meta.py
@@ -588,19 +588,16 @@ class SlidingSyncRoomsMetaTestCase(SlidingSyncBase):
         )
 
         # Make sure the list includes the rooms in the right order
-        self.assertListEqual(
-            list(response_body["lists"]["foo-list"]["ops"]),
-            [
-                {
-                    "op": "SYNC",
-                    "range": [0, 1],
-                    # room1 sorts before room2 because it has the latest event (the
-                    # reaction)
-                    "room_ids": [room_id1, room_id2],
-                }
-            ],
+        self.assertEqual(
+            len(response_body["lists"]["foo-list"]["ops"]),
+            1,
             response_body["lists"]["foo-list"],
         )
+        op = response_body["lists"]["foo-list"]["ops"][0]
+        self.assertEqual(op["op"], "SYNC")
+        self.assertEqual(op["range"], [0, 1])
+        # Note that we don't order the ops anymore, so we need to compare sets.
+        self.assertIncludes(set(op["room_ids"]), {room_id1, room_id2}, exact=True)
 
         # The `bump_stamp` for room1 should point at the latest message (not the
         # reaction since it's not one of the `DEFAULT_BUMP_EVENT_TYPES`)
-- 
GitLab