-
Notifications
You must be signed in to change notification settings - Fork 269
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(ui): Fix performance of ReadReceiptTimelineUpdate::apply
#4612
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #4612 +/- ##
==========================================
- Coverage 85.74% 85.73% -0.02%
==========================================
Files 291 291
Lines 33306 33329 +23
==========================================
+ Hits 28558 28574 +16
- Misses 4748 4755 +7 ☔ View full report in Codecov by Sentry. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice improvement!
} else { | ||
warn!("received a read receipt for a local item, this should not be possible"); | ||
} | ||
} | ||
|
||
/// Apply this update to the timeline. | ||
fn apply( | ||
self, | ||
mut self, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this change spurious? Doesn't seem required according to the rest of the diff…
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is necessary because remove_old_receipt
takes a &mut self
.
This patch improves the performance of `ReadReceiptTimelineUpdate::apply`, which does 2 things: it calls `remove_old_receipt` and `add_new_receipt`. Both of them need an timeline item position. Until this patch, `rfind_event_by_id` was used and was the bottleneck. The improvement is twofold as is as follows. First off, when collecting data to create `ReadReceiptTimelineUpdate`, the timeline item position can be known ahead of time by using `EventMeta::timeline_item_index`. This data is not always available, for example if the timeline item isn't created yet. But let's try to collect these data if there are some. Second, inside `ReadReceiptTimelineUpdate::remove_old_receipt`, we use the timeline item position collected from `EventMeta` if it exists. Otherwise, let's fallback to a similar `rfind_event_by_id` pattern, without using intermediate types. It's more straightforward here: we don't need an `EventTimelineItemWithId`, we only need the position. Once the position is known, it is stored in `Self` (!), this is the biggest improvement here. Le't see why. Finally, inside `ReadReceiptTimelineUpdate::add_new_receipt`, we use the timeline item position collected from `EventMeta` if it exists, similarly to what `remove_old_receipt` does. Otherwise, let's fallback to an iterator to find the position. However, instead of iterating over **all** items, we can skip the first ones, up to the position of the timeline item holding the old receipt, so up to the position found by `remove_old_receipt`. I'm testing this patch with the `test_lazy_back_pagination` test in matrix-org#4594. With 10_000 events in the sync, the `ReadReceipts::maybe_update_read_receipt` method was taking 52% of the whole execution time. With this patch, it takes 8.1%.
84ade87
to
b59b0ea
Compare
This patch adds matrix-org#4601, matrix-org#4608, matrix-org#4612 and matrix-org#4616 in their respective `CHANGELOG.md`s. +
This patch adds matrix-org#4601, matrix-org#4608, matrix-org#4612 and matrix-org#4616 in their respective `CHANGELOG.md`s.
This patch adds matrix-org#4601, matrix-org#4608, matrix-org#4612 and matrix-org#4616 in their respective `CHANGELOG.md`s.
This patch improves the performance of
ReadReceiptTimelineUpdate::apply
, which does 2 things: it callsremove_old_receipt
andadd_new_receipt
. Both of them need a timeline item position. Until this patch,rfind_event_by_id
was used and was the bottleneck. The improvement is twofold and is as follows.First off, when collecting data to create
ReadReceiptTimelineUpdate
, the timeline item position can be known ahead of time by usingEventMeta::timeline_item_index
. This data is not always available though, for example if the timeline item isn't created yet. But let's try to collect these data if there are some.Second, inside
ReadReceiptTimelineUpdate::remove_old_receipt
, we use the timeline item position collected fromEventMeta
if it exists. Otherwise, let's fallback to a similarrfind_event_by_id
pattern, without using intermediate types. It's more straightforward here: we don't need anEventTimelineItemWithId
, we only need the position. Once the position is known, it is stored inSelf
(!), this is the biggest improvement here. Le't see why.Finally, inside
ReadReceiptTimelineUpdate::add_new_receipt
, we use the timeline item position collected fromEventMeta
if it exists, similarly to whatremove_old_receipt
does. Otherwise, let's fallback to an iterator to find the position. However, instead of iterating over all items, we can skip the first ones, up to the position of the timeline item holding the old receipt, so up to the position found byremove_old_receipt
.I'm testing this patch with the
test_lazy_back_pagination
test in #4594. With 10_000 events in the sync, theReadReceipts::maybe_update_read_receipt
method was taking 52% of the whole execution time. With this patch, it takes 8.1%.The call tree of
ReadReceipts::maybe_update_read_receipt
and its flamegraph before this patch…and after…


EventCache
storage #3280