bench: add restore session benchmark

Signed-off-by: Benjamin Bouvier <public@benj.me>
This commit is contained in:
Benjamin Bouvier
2023-05-11 17:36:29 +02:00
parent 18954a6ba5
commit 3928259bb5
3 changed files with 133 additions and 1 deletions

2
Cargo.lock generated
View File

@@ -537,6 +537,8 @@ name = "benchmarks"
version = "1.0.0"
dependencies = [
"criterion",
"matrix-sdk",
"matrix-sdk-base",
"matrix-sdk-crypto",
"matrix-sdk-sled",
"matrix-sdk-sqlite",

View File

@@ -9,10 +9,12 @@ publish = false
[dependencies]
criterion = { version = "0.4.0", features = ["async", "async_tokio", "html_reports"] }
matrix-sdk-base = { path = "../crates/matrix-sdk-base" }
matrix-sdk-crypto = { path = "../crates/matrix-sdk-crypto", version = "0.6.0"}
matrix-sdk-sqlite = { path = "../crates/matrix-sdk-sqlite", version = "0.1.0", default-features = false, features = ["crypto-store"] }
matrix-sdk-sled = { path = "../crates/matrix-sdk-sled", version = "0.2.0", default-features = false, features = ["crypto-store"] }
matrix-sdk-sled = { path = "../crates/matrix-sdk-sled", version = "0.2.0", features = ["crypto-store"] }
matrix-sdk-test = { path = "../testing/matrix-sdk-test", version = "0.6.0"}
matrix-sdk = { path = "../crates/matrix-sdk" }
ruma = { workspace = true }
serde_json = { workspace = true }
tempfile = "3.3.0"
@@ -24,3 +26,7 @@ pprof = { version = "0.11.0", features = ["flamegraph", "criterion"] }
[[bench]]
name = "crypto_bench"
harness = false
[[bench]]
name = "store_bench"
harness = false

View File

@@ -0,0 +1,124 @@
use criterion::*;
use matrix_sdk::{config::StoreConfig, Client, RoomInfo, RoomState, Session, StateChanges};
use matrix_sdk_base::{store::MemoryStore, StateStore as _};
use matrix_sdk_sled::SledStateStore;
use matrix_sdk_sqlite::SqliteStateStore;
use ruma::{device_id, user_id, RoomId};
use tokio::runtime::Builder;
fn criterion() -> Criterion {
#[cfg(target_os = "linux")]
let criterion = Criterion::default().with_profiler(pprof::criterion::PProfProfiler::new(
100,
pprof::criterion::Output::Flamegraph(None),
));
#[cfg(not(target_os = "linux"))]
let criterion = Criterion::default();
criterion
}
/// Number of joined rooms in the benchmark.
const NUM_JOINED_ROOMS: usize = 10000;
/// Number of stripped rooms in the benchmark.
const NUM_STRIPPED_JOINED_ROOMS: usize = 10000;
pub fn restore_session(c: &mut Criterion) {
let runtime = Builder::new_multi_thread().build().expect("Can't create runtime");
// Create a fake list of changes, and a session to recover from.
let mut changes = StateChanges::default();
for i in 0..NUM_JOINED_ROOMS {
let room_id = RoomId::parse(format!("!room{i}:example.com")).unwrap().to_owned();
changes.add_room(RoomInfo::new(&room_id, RoomState::Joined));
}
for i in 0..NUM_STRIPPED_JOINED_ROOMS {
let room_id = RoomId::parse(format!("!strippedroom{i}:example.com")).unwrap().to_owned();
changes.add_stripped_room(RoomInfo::new(&room_id, RoomState::Joined));
}
let session = Session {
access_token: "OHEY".to_owned(),
refresh_token: None,
user_id: user_id!("@somebody:example.com").to_owned(),
device_id: device_id!("DEVICE_ID").to_owned(),
};
// Start the benchmark.
let mut group = c.benchmark_group("Client reload");
group.throughput(Throughput::Elements(100));
const NAME: &str = "restore a session";
// Memory
let mem_store = MemoryStore::new();
runtime.block_on(mem_store.save_changes(&changes)).expect("initial filling of mem failed");
group.bench_with_input(BenchmarkId::new("memory store", NAME), &mem_store, |b, store| {
b.to_async(&runtime).iter(|| async {
let client = Client::builder()
.homeserver_url("https://matrix.example.com")
.store_config(StoreConfig::new().state_store(store.clone()))
.build()
.await
.expect("Can't build client");
client.restore_session(session.clone()).await.expect("couldn't restore session");
})
});
// Sled
let sled_path = tempfile::tempdir().unwrap().path().to_path_buf();
let sled_store =
SledStateStore::builder().path(sled_path).build().expect("Can't create sled store");
runtime.block_on(sled_store.save_changes(&changes)).expect("initial filling of sled failed");
group.bench_with_input(BenchmarkId::new("sled store", NAME), &sled_store, |b, store| {
b.to_async(&runtime).iter(|| async {
let client = Client::builder()
.homeserver_url("https://matrix.example.com")
.store_config(StoreConfig::new().state_store(store.clone()))
.build()
.await
.expect("Can't build client");
client.restore_session(session.clone()).await.expect("couldn't restore session");
})
});
// Sqlite
let sqlite_dir = tempfile::tempdir().unwrap();
let sqlite_store = runtime.block_on(SqliteStateStore::open(sqlite_dir.path(), None)).unwrap();
runtime
.block_on(sqlite_store.save_changes(&changes))
.expect("initial filling of sqlite failed");
group.bench_with_input(BenchmarkId::new("sqlite store", NAME), &sqlite_store, |b, store| {
b.to_async(&runtime).iter(|| async {
let client = Client::builder()
.homeserver_url("https://matrix.example.com")
.store_config(StoreConfig::new().state_store(store.clone()))
.build()
.await
.expect("Can't build client");
client.restore_session(session.clone()).await.expect("couldn't restore session");
})
});
{
let _guard = runtime.enter();
drop(sqlite_store);
}
group.finish()
}
criterion_group! {
name = benches;
config = criterion();
targets = restore_session
}
criterion_main!(benches);