diff --git a/lib/benches/store.rs b/lib/benches/store.rs index 815b9590..37f479d6 100644 --- a/lib/benches/store.rs +++ b/lib/benches/store.rs @@ -4,9 +4,11 @@ use oxigraph::io::GraphFormat; use oxigraph::model::GraphNameRef; use oxigraph::sparql::{Query, QueryResults, Update}; use oxigraph::store::Store; -use std::fs::File; +use rand::random; +use std::env::temp_dir; +use std::fs::{remove_dir_all, File}; use std::io::{BufRead, BufReader, Cursor, Read}; -use std::path::Path; +use std::path::{Path, PathBuf}; fn store_load(c: &mut Criterion) { let mut data = Vec::new(); @@ -17,27 +19,22 @@ fn store_load(c: &mut Criterion) { let mut group = c.benchmark_group("store load"); group.throughput(Throughput::Bytes(data.len() as u64)); group.sample_size(10); - group.bench_function("load BSBM explore 1000", |b| { + group.bench_function("load BSBM explore 1000 in memory", |b| { b.iter(|| { let store = Store::new().unwrap(); - store - .load_graph( - Cursor::new(&data), - GraphFormat::NTriples, - GraphNameRef::DefaultGraph, - None, - ) - .unwrap(); + do_load(&store, &data); + }) + }); + group.bench_function("load BSBM explore 1000 in on disk", |b| { + b.iter(|| { + let path = TempDir::default(); + let store = Store::open(&path.0).unwrap(); + do_load(&store, &data); }) }); } -fn store_query_and_update(c: &mut Criterion) { - let mut data = Vec::new(); - read_data("explore-1000.nt.zst") - .read_to_end(&mut data) - .unwrap(); - let store = Store::new().unwrap(); +fn do_load(store: &Store, data: &[u8]) { store .load_graph( Cursor::new(&data), @@ -46,6 +43,14 @@ fn store_query_and_update(c: &mut Criterion) { None, ) .unwrap(); +} + +fn store_query_and_update(c: &mut Criterion) { + let mut data = Vec::new(); + read_data("explore-1000.nt.zst") + .read_to_end(&mut data) + .unwrap(); + let operations = read_data("mix-exploreAndUpdate-1000.tsv.zst") .lines() .map(|l| { @@ -60,32 +65,59 @@ fn store_query_and_update(c: &mut Criterion) { } }) .collect::>(); + let query_operations = operations + .iter() + .filter(|o| matches!(o, Operation::Query(_))) + .cloned() + .collect::>(); let mut group = c.benchmark_group("store operations"); group.throughput(Throughput::Elements(operations.len() as u64)); group.sample_size(10); - group.bench_function("BSBM explore 1000 queryAndUpdate", |b| { - b.iter(|| { - for operation in &operations { - match operation { - Operation::Query(q) => match store.query(q.clone()).unwrap() { - QueryResults::Boolean(_) => (), - QueryResults::Solutions(s) => { - for s in s { - s.unwrap(); - } - } - QueryResults::Graph(g) => { - for t in g { - t.unwrap(); - } - } - }, - Operation::Update(u) => store.update(u.clone()).unwrap(), + + { + let memory_store = Store::new().unwrap(); + do_load(&memory_store, &data); + group.bench_function("BSBM explore 1000 query in memory", |b| { + b.iter(|| run_operation(&memory_store, &query_operations)) + }); + group.bench_function("BSBM explore 1000 queryAndUpdate in memory", |b| { + b.iter(|| run_operation(&memory_store, &operations)) + }); + } + + { + let path = TempDir::default(); + let disk_store = Store::open(&path.0).unwrap(); + do_load(&disk_store, &data); + group.bench_function("BSBM explore 1000 query on disk", |b| { + b.iter(|| run_operation(&disk_store, &query_operations)) + }); + group.bench_function("BSBM explore 1000 queryAndUpdate on disk", |b| { + b.iter(|| run_operation(&disk_store, &operations)) + }); + } +} + +fn run_operation(store: &Store, operations: &[Operation]) { + for operation in operations { + match operation { + Operation::Query(q) => match store.query(q.clone()).unwrap() { + QueryResults::Boolean(_) => (), + QueryResults::Solutions(s) => { + for s in s { + s.unwrap(); + } } - } - }) - }); + QueryResults::Graph(g) => { + for t in g { + t.unwrap(); + } + } + }, + Operation::Update(u) => store.update(u.clone()).unwrap(), + } + } } criterion_group!(store, store_query_and_update, store_load); @@ -113,7 +145,22 @@ fn read_data(file: &str) -> impl BufRead { BufReader::new(zstd::Decoder::new(File::open(file).unwrap()).unwrap()) } +#[derive(Clone)] enum Operation { Query(Query), Update(Update), } + +struct TempDir(PathBuf); + +impl Default for TempDir { + fn default() -> Self { + Self(temp_dir().join(format!("oxigraph-bench-{}", random::()))) + } +} + +impl Drop for TempDir { + fn drop(&mut self) { + remove_dir_all(&self.0).unwrap() + } +}