diff options
author | Alexey Rusakov <Kitsune-Ral@users.sf.net> | 2022-07-16 20:31:12 +0200 |
---|---|---|
committer | Alexey Rusakov <Kitsune-Ral@users.sf.net> | 2022-07-16 21:55:15 +0200 |
commit | 4770d303b7141971fa9a25f85874e6bbe71776d9 (patch) | |
tree | 24c45fb29478079ac610502ed6948f50298faac9 /lib/application-service/definitions/user.h | |
parent | cc8753612f2f45b18a9c924920395fb5f4c57078 (diff) | |
download | libquotient-4770d303b7141971fa9a25f85874e6bbe71776d9.tar.gz libquotient-4770d303b7141971fa9a25f85874e6bbe71776d9.zip |
Speed up read receipt updates
Profiling revealed 3 inefficiencies in read receipts code - and given
there are a lot of them coming, these inefficiences quickly add up.
Fixing them allows to slash read receipt processing time by 60%, and
the total time of updating a room by more than a half.
1. Room::lastReadEventChanged() is emitted per receipt. This can be
taxing on initial syncs or in bigger rooms; this commit converts it
to an aggregate signal only emitted once per sync room batch and
carrying the list of all user ids (more on that below) with updated
read receipts.
For that, Room::P::setLastReadEvent() is split into
Room::P::setLocalLastReadEvent() that is called whenever the local
read receipt has to be updated, and setLastReadEvent() proper that is
very fast and only updates the internal data structures, nothing else.
setLocalLastEvent() calls it, as does processEphemeralEvents(); both
take responsibility to emit lastReadEventChanged() depending on the
outcome of setLastReadEvent() invocation(s).
2. Massively aggravating the above point, user id from each read receipt
is turned to a User object - and since most of the users are unknown
at early moments, this causes thousands of allocations. Therefore
the new aggregated lastReadEventChanged() only carries user ids, and
clients will have to resolve them to User objects if they need.
3. Despite fairly tight conditions (note we're talking about thousands
of receipts), Quotient still creates an intermediate C++ structure
(EventsWithReceipts), only for the sake of passing it to
processEphemeralEvent() that immediately disassembles it back again,
converting to a series of calls to set(Local)LastReadEvent(). To fix
this, processEphemeralEvent() now takes the event content JSON
directly and iterates over it instead.
Aside from that, a few extraneous conditions and logging has been
removed and the whole function rewritten with switchOnType() to reduce
cognitive complexity.
Diffstat (limited to 'lib/application-service/definitions/user.h')
0 files changed, 0 insertions, 0 deletions