chore(bench): Add the room_list benchmark.
This patch adds the `room_list` benchmark. The goal is to measure the time it takes to create a room list, to sort it, to filter and to “display” it.
This commit is contained in:
@@ -14,13 +14,16 @@ release = false
|
||||
codspeed = []
|
||||
|
||||
[dependencies]
|
||||
assert_matches.workspace = true
|
||||
criterion = { version = "3.0.5", features = ["async", "async_tokio", "html_reports"], package = "codspeed-criterion-compat" }
|
||||
futures-util.workspace = true
|
||||
matrix-sdk = { workspace = true, features = ["native-tls", "e2e-encryption", "sqlite", "testing"] }
|
||||
matrix-sdk-base.workspace = true
|
||||
matrix-sdk-crypto.workspace = true
|
||||
matrix-sdk-sqlite = { workspace = true, features = ["crypto-store"] }
|
||||
matrix-sdk-test.workspace = true
|
||||
matrix-sdk-ui.workspace = true
|
||||
rand.workspace = true
|
||||
ruma.workspace = true
|
||||
serde.workspace = true
|
||||
serde_json.workspace = true
|
||||
@@ -51,3 +54,7 @@ harness = false
|
||||
[[bench]]
|
||||
name = "event_cache"
|
||||
harness = false
|
||||
|
||||
[[bench]]
|
||||
name = "room_list"
|
||||
harness = false
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
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, event_factory::EventFactory};
|
||||
use matrix_sdk_ui::{
|
||||
RoomListService, eyeball_im::VectorDiff, room_list_service::filters::new_filter_non_left,
|
||||
};
|
||||
use rand::{distributions::Uniform, prelude::Distribution};
|
||||
use ruma::{EventId, 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::thread_rng();
|
||||
let server_ts_range = Uniform::from(100..1000);
|
||||
|
||||
for room_nth in 0..NUMBER_OF_ROOMS {
|
||||
let room_id = RoomId::parse(format!("!r{room_nth}")).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| {
|
||||
let event_id = EventId::parse(format!("$ev{room_nth}_{event_nth}")).unwrap();
|
||||
|
||||
event_factory.text_msg("a").sender(&sender_id).event_id(&event_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);
|
||||
Reference in New Issue
Block a user