matrix-rust-sdk: Performance of `Room.members`/`get_member` in large rooms is bad

On Element Android X and Element iOS X we’ve noticed that it takes a significant amount of time to get the list of members in a room. Eyeballing the network requests and UI, for a room with ~10k members there’s an approximately 10-12 second delay between the HTTP request to get members returning, and the UI actually showing anything.

I initially thought this was due to the volume of FFI calls we were making, but I’ve done some hacky tracing and it seems like all the time is spent in Room.members. For the room with 10k members, it takes 30-50ms to get the userIDs for all members, then around 10 seconds in total to call get_member for each of those users.

Inside get_member nothing in particular stands out:

  • store.get_member_event takes 2.5s in aggregate
  • store.get_presence_event takes 1.7s
  • store.get_profile takes 1.9s
  • store.get_users_with_display_name (for the display name ambiguity check) takes 2.0s

There are a couple more bits that I didn’t explicitly time, but based on the total time taken I’d imagine they are similar. (Someone with an actual profiler set up may be able to provide more insight here).

Steps to reproduce:

  • Add tracing lines to the start and end of Room.members
  • Build a version of EAX or EIX with the modified SDK
  • Join the Element Android channel
  • Open the room details screen and observe loading spinner on the member button
  • Observe ~10s gap in between trace statements

About this issue

  • Original URL
  • State: open
  • Created a year ago
  • Comments: 16 (12 by maintainers)

Most upvoted comments

Room.membersBlocking() is somehow faster than Room.members(), it can be up to 12x faster if the 2nd attempt wasn’t a fluke or a failure that somehow reported back data.

If the two calls were following each other and there were no gappy sync in this room, then the members are up to date, and the SDK won’t reissue a query for the room members. It’s likely what you observed here, explaining why the request never got sent.

The app was restarted between each try, <del>so unless they’re persisted to DB I don’t think any data would survive.</del> Of course they’re persisted to DB 🤦 .

That’ll speed up showing the count on the details screen, but obviously it just moves the delay to a different place if the user actually wants to see the member list 😃

Indeed. We should still use this issue to discuss / fix the slow load of the overall member list.

Yeah, we can easily access those. Not sure why we’re not using them already! I’ve opened https://github.com/vector-im/element-x-android/issues/505 to do that (I’ll get to it today or tomorrow most likely).

That’ll speed up showing the count on the details screen, but obviously it just moves the delay to a different place if the user actually wants to see the member list 😃

Just to record what was said on Matrix about this: The fix here will be to provide an API that batches the accesses to the store. Kévin offered to take a stab at it 😃