mirror of
https://github.com/matrix-org/matrix-rust-sdk.git
synced 2026-08-04 03:52:19 -04:00
102 lines
3.8 KiB
Rust
102 lines
3.8 KiB
Rust
use assert_matches::assert_matches;
|
||
use criterion::{BenchmarkId, Criterion, Throughput, criterion_group, criterion_main};
|
||
use futures_util::pin_mut;
|
||
use matrix_sdk::{stream::StreamExt, test_utils::mocks::MatrixMockServer};
|
||
use matrix_sdk_test::{JoinedRoomBuilder, base64_sha256_hash, event_factory::EventFactory};
|
||
use matrix_sdk_ui::{
|
||
RoomListService, eyeball_im::VectorDiff, room_list_service::filters::new_filter_non_left,
|
||
};
|
||
use rand::{distr::Uniform, prelude::Distribution};
|
||
use ruma::{OwnedRoomId, RoomId, owned_user_id};
|
||
use tokio::runtime::Builder;
|
||
|
||
/// Benchmark the time it takes to create a room list.
|
||
pub fn create(c: &mut Criterion) {
|
||
const NUMBER_OF_ROOMS: usize = 1000;
|
||
const NUMBER_OF_EVENTS_PER_ROOM: usize = 1000;
|
||
|
||
let runtime = Builder::new_multi_thread().enable_all().build().expect("Can't create runtime");
|
||
|
||
let (server, client) = runtime.block_on(async {
|
||
let server = MatrixMockServer::new().await;
|
||
let client = server.client_builder().build().await;
|
||
client.event_cache().subscribe().unwrap();
|
||
|
||
(server, client)
|
||
});
|
||
|
||
let sender_id = owned_user_id!("@mnt_io:matrix.org");
|
||
let mut rand = rand::rng();
|
||
let server_ts_range = Uniform::try_from(100..1000).unwrap();
|
||
|
||
for room_nth in 0..NUMBER_OF_ROOMS {
|
||
// Synapse's room IDs for rooms v1 to v11 have an 18 characters localpart.
|
||
let raw_room_id = format!("!arsgratiaartis{room_nth:04}:example.com");
|
||
|
||
let room_id = if room_nth % 10 == 9 {
|
||
// Make 1 in 10 rooms use a room v12 ID, which is a base64 hash similar to an
|
||
// event ID.
|
||
RoomId::new_v2(&base64_sha256_hash(raw_room_id.as_bytes())).unwrap()
|
||
} else {
|
||
OwnedRoomId::try_from(raw_room_id).unwrap()
|
||
};
|
||
|
||
let first_server_ts = server_ts_range.sample(&mut rand);
|
||
let event_factory = EventFactory::new().room(&room_id).server_ts(first_server_ts);
|
||
|
||
let events = (0..NUMBER_OF_EVENTS_PER_ROOM)
|
||
.map(|event_nth| {
|
||
event_factory
|
||
.text_msg(format!("a {room_nth}_{event_nth}"))
|
||
.sender(&sender_id)
|
||
.into_raw_sync()
|
||
})
|
||
.collect::<Vec<_>>();
|
||
|
||
let _room = runtime.block_on(async {
|
||
server
|
||
.sync_room(&client, JoinedRoomBuilder::new(&room_id).add_timeline_bulk(events))
|
||
.await
|
||
});
|
||
}
|
||
|
||
let mut group = c.benchmark_group("RoomList");
|
||
group.throughput(Throughput::Elements(NUMBER_OF_ROOMS.try_into().unwrap()));
|
||
|
||
group.bench_function(
|
||
BenchmarkId::new(
|
||
"Create",
|
||
format!("{NUMBER_OF_ROOMS} rooms × {NUMBER_OF_EVENTS_PER_ROOM} events"),
|
||
),
|
||
|bencher| {
|
||
bencher.to_async(&runtime).iter(|| async {
|
||
let room_list_service = RoomListService::new(client.clone())
|
||
.await
|
||
.expect("build the room list service");
|
||
let room_list = room_list_service.all_rooms().await.expect("fetch `all_rooms`");
|
||
let (entries_stream, entries_controller) =
|
||
room_list.entries_with_dynamic_adapters(20);
|
||
|
||
// Setting the filter will trigger the entries stream computation.
|
||
entries_controller.set_filter(Box::new(new_filter_non_left()));
|
||
|
||
pin_mut!(entries_stream);
|
||
let update = entries_stream.next().await.expect("receiving the reset update");
|
||
assert_eq!(update.len(), 1);
|
||
assert_matches!(&update[0], VectorDiff::Reset { values } => {
|
||
assert_eq!(values.len(), 20);
|
||
});
|
||
});
|
||
},
|
||
);
|
||
|
||
group.finish();
|
||
}
|
||
|
||
criterion_group! {
|
||
name = room_list;
|
||
config = Criterion::default();
|
||
targets = create
|
||
}
|
||
criterion_main!(room_list);
|