From b5a6e7b99859d9aad2a7fb67f06337b6ff68d421 Mon Sep 17 00:00:00 2001 From: Ziyang Hu Date: Sun, 4 Dec 2022 21:04:34 +0800 Subject: [PATCH] benchmarks --- Cargo.toml | 3 + cozo-core/benches/pokec.rs | 1042 +++++++++++++++++++++++++++++++++ cozo-core/tests/air_routes.rs | 357 ++++++----- 3 files changed, 1259 insertions(+), 143 deletions(-) create mode 100644 cozo-core/benches/pokec.rs diff --git a/Cargo.toml b/Cargo.toml index 77858b2d..73f1bd21 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,3 +10,6 @@ members = [ "cozo-lib-python", "cozo-lib-nodejs" ] + +[profile.bench] +lto = true \ No newline at end of file diff --git a/cozo-core/benches/pokec.rs b/cozo-core/benches/pokec.rs new file mode 100644 index 00000000..a83e3961 --- /dev/null +++ b/cozo-core/benches/pokec.rs @@ -0,0 +1,1042 @@ +/* + * Copyright 2022, The Cozo Project Authors. + * + * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + * If a copy of the MPL was not distributed with this file, + * You can obtain one at https://mozilla.org/MPL/2.0/. + */ +#![feature(test)] + +extern crate test; + +use std::collections::BTreeMap; +use std::fs::File; +use std::io::BufRead; +use std::path::{Path, PathBuf}; +use std::time::Instant; +use std::{env, io, mem}; +use test::Bencher; + +use lazy_static::{initialize, lazy_static}; +use rand::Rng; +use regex::Regex; +use serde_json::json; + +use cozo::{DbInstance, NamedRows}; + +lazy_static! { + static ref SIZES: (usize, usize) = { + let size = env::var("COZO_BENCH_POKEC_SIZE").unwrap_or("medium".to_string()); + match &size as &str { + "small" => (10000, 121716), + "medium" => (100000, 1768515), + "large" => (1632803, 30622564), + _ => panic!() + } + }; + + static ref TEST_DB: DbInstance = { + let data_dir = PathBuf::from(env::var("COZO_BENCH_POKEC_DIR").unwrap()); + let db_kind = env::var("COZO_TEST_DB_ENGINE").unwrap_or("mem".to_string()); + let mut db_path = data_dir.clone(); + let data_size = env::var("COZO_BENCH_POKEC_SIZE").unwrap_or("medium".to_string()); + let batch_size = env::var("COZO_BENCH_POKEC_BATCH") + .unwrap() + .parse::() + .unwrap(); + db_path.push(format!("{}-{}.db", db_kind, data_size)); + let _ = std::fs::remove_file(&db_path); + let _ = std::fs::remove_dir_all(&db_path); + + let db = DbInstance::new(&db_kind, db_path.to_str().unwrap(), "").unwrap(); + + let mut backup_path = data_dir.clone(); + backup_path.push(format!("backup-{}.db", data_size)); + if Path::exists(&backup_path) { + println!("restore from backup"); + db.restore_backup(backup_path.to_str().unwrap()).unwrap(); + } else { + let mut file_path = data_dir.clone(); + file_path.push(format!("pokec_{}_import.cypher", data_size)); + + // dbg!(&db_kind); + // dbg!(&data_dir); + // dbg!(&file_path); + // dbg!(&data_size); + // dbg!(&n_threads); + + if db.run_script( + r#" + {:create user {uid: Int => cmpl_pct: Int, gender: String?, age: Int?}} + {:create friends {fr: Int, to: Int}} + {:create friends.rev {to: Int, fr: Int}} + "#, + Default::default(), + ).is_err() { + return db + } + + // NODE_PATTERN = re.compile(r'CREATE \(:User {id: (\d+), completion_percentage: (\d+), gender: "(\w+)", age: (\d+)}\);') + // NODE_PARTIAL_PATTERN = re.compile(r'CREATE \(:User {id: (\d+), completion_percentage: (\d+)}\);') + // EDGE_PATTERN = re.compile(r'MATCH \(n:User {id: (\d+)}\), \(m:User {id: (\d+)}\) CREATE \(n\)-\[e: Friend\]->\(m\);') + let node_re = Regex::new(r#"CREATE \(:User \{id: (\d+), completion_percentage: (\d+), gender: "(\w+)", age: (\d+)}\);"#).unwrap(); + let node_partial_re = + Regex::new(r#"CREATE \(:User \{id: (\d+), completion_percentage: (\d+)}\);"#).unwrap(); + let edge_re = Regex::new(r#"MATCH \(n:User \{id: (\d+)}\), \(m:User \{id: (\d+)}\) CREATE \(n\)-\[e: Friend]->\(m\);"#).unwrap(); + + let file = File::open(&file_path).unwrap(); + let mut friends = Vec::with_capacity(batch_size); + let mut users = Vec::with_capacity(batch_size); + let mut push_to_users = |row: Option>, force: bool| { + if let Some(row) = row { + users.push(row); + } + if users.len() >= batch_size || (force && !users.is_empty()) { + let mut new_rows = Vec::with_capacity(batch_size); + mem::swap(&mut new_rows, &mut users); + db.import_relations(BTreeMap::from([( + "user".to_string(), + NamedRows { + headers: vec![ + "uid".to_string(), + "cmpl_pct".to_string(), + "gender".to_string(), + "age".to_string(), + ], + rows: new_rows, + }, + )])) + .unwrap(); + } + }; + + let mut push_to_friends = |row: Option>, force: bool| { + if let Some(row) = row { + friends.push(row); + } + if friends.len() >= batch_size || (force && !friends.is_empty()) { + let mut new_rows = Vec::with_capacity(batch_size); + mem::swap(&mut new_rows, &mut friends); + db.import_relations(BTreeMap::from([ + ( + "friends".to_string(), + NamedRows { + headers: vec!["fr".to_string(), "to".to_string()], + rows: new_rows.clone(), + }, + ), + ( + "friends.rev".to_string(), + NamedRows { + headers: vec!["fr".to_string(), "to".to_string()], + rows: new_rows, + }, + ), + ])) + .unwrap(); + } + }; + + let import_time = Instant::now(); + let mut n_rows = 0usize; + for line in io::BufReader::new(file).lines() { + let line = line.unwrap(); + if let Some(data) = edge_re.captures(&line) { + n_rows += 2; + let fr = data.get(1).unwrap().as_str().parse::().unwrap(); + let to = data.get(2).unwrap().as_str().parse::().unwrap(); + push_to_friends(Some(vec![json!(fr), json!(to)]), false); + continue; + } + if let Some(data) = node_re.captures(&line) { + n_rows += 1; + let uid = data.get(1).unwrap().as_str().parse::().unwrap(); + let cmpl_pct = data.get(2).unwrap().as_str().parse::().unwrap(); + let gender = data.get(3).unwrap().as_str(); + let age = data.get(4).unwrap().as_str().parse::().unwrap(); + push_to_users( + Some(vec![json!(uid), json!(cmpl_pct), json!(gender), json!(age)]), + false, + ); + continue; + } + if let Some(data) = node_partial_re.captures(&line) { + n_rows += 1; + let uid = data.get(1).unwrap().as_str().parse::().unwrap(); + let cmpl_pct = data.get(2).unwrap().as_str().parse::().unwrap(); + push_to_users( + Some(vec![ + json!(uid), + json!(cmpl_pct), + serde_json::Value::Null, + serde_json::Value::Null, + ]), + false, + ); + continue; + } + if line.len() < 3 { + continue; + } + panic!("Err: {}", line) + } + push_to_users(None, true); + push_to_friends(None, true); + dbg!(import_time.elapsed()); + dbg!((n_rows as f64) / import_time.elapsed().as_secs_f64()); + } + db + }; +} + +type QueryFn = fn() -> (); +const READ_QUERIES: [QueryFn; 1] = [single_vertex]; +const WRITE_QUERIES: [QueryFn; 2] = [single_edge_write, single_vertex_write]; +const UPDATE_QUERIES: [QueryFn; 1] = [single_vertex_update]; +#[allow(dead_code)] +const AGGREGATE_QUERIES: [QueryFn; 4] = [ + aggregation, + aggregation_filter, + aggregation_distinct, + min_max, +]; +const ANALYTICAL_QUERIES: [QueryFn; 15] = [ + expansion_1, + expansion_2, + expansion_3, + expansion_4, + expansion_1_filter, + expansion_2_filter, + expansion_3_filter, + expansion_4_filter, + neighbours_2, + neighbours_2_filter, + neighbours_2_data, + neighbours_2_filter_data, + pattern_cycle, + pattern_long, + pattern_short, +]; + +fn single_vertex() { + let i = rand::thread_rng().gen_range(1..SIZES.0); + TEST_DB + .run_script( + "?[cmpl_pct, gender, age] := *user{uid: $id, cmpl_pct, gender, age}", + BTreeMap::from([("id".to_string(), json!(i))]), + ) + .unwrap(); +} + +fn single_vertex_write() { + let i = rand::thread_rng().gen_range(1..SIZES.0 * 10); + TEST_DB + .run_script( + "?[uid, cmpl_pct, gender, age] <- [[$id, 0, null, null]] :put user {uid => cmpl_pct, gender, age}", + BTreeMap::from([("id".to_string(), json!(i))]), + ) + .unwrap(); +} + +fn single_edge_write() { + let i = rand::thread_rng().gen_range(1..SIZES.0); + let mut j = rand::thread_rng().gen_range(1..SIZES.0); + while j == i { + j = rand::thread_rng().gen_range(1..SIZES.0); + } + TEST_DB + .run_script( + r#" + {?[fr, to] <- [[$i, $j]] :put friends {fr, to}} + {?[fr, to] <- [[$i, $j]] :put friends.rev {fr, to}} + "#, + BTreeMap::from([("i".to_string(), json!(i)), ("j".to_string(), json!(j))]), + ) + .unwrap(); +} + +fn single_vertex_update() { + let i = rand::thread_rng().gen_range(1..SIZES.0); + TEST_DB + .run_script( + r#" + ?[uid, cmpl_pct, age, gender] := uid = $id, *user{uid, age, gender}, cmpl_pct = -1 + :put user {uid => cmpl_pct, age, gender} + "#, + BTreeMap::from([("id".to_string(), json!(i))]), + ) + .unwrap(); +} + +fn aggregation() { + TEST_DB + .run_script("?[age, count(uid)] := *user{uid, age}", Default::default()) + .unwrap(); +} + +fn aggregation_distinct() { + TEST_DB + .run_script("?[count_unique(age)] := *user{age}", Default::default()) + .unwrap(); +} + +fn aggregation_filter() { + TEST_DB + .run_script( + "?[age, count(uid)] := *user{uid, age}, try(age >= 18, false)", + Default::default(), + ) + .unwrap(); +} + +fn min_max() { + TEST_DB + .run_script( + "?[min(uid), max(uid), mean(uid)] := *user{uid, age}", + Default::default(), + ) + .unwrap(); +} + +fn expansion_1() { + let mut rng = rand::thread_rng(); + let i = rng.gen_range(1..SIZES.0); + TEST_DB + .run_script( + "?[to] := *friends{fr: $id, to}", + BTreeMap::from([("id".to_string(), json!(i))]), + ) + .unwrap(); +} + +fn expansion_1_filter() { + let mut rng = rand::thread_rng(); + let i = rng.gen_range(1..SIZES.0); + TEST_DB + .run_script( + "?[to] := *friends{fr: $id, to}, *user{uid: to, age}, try(age >= 18, false)", + BTreeMap::from([("id".to_string(), json!(i))]), + ) + .unwrap(); +} + +fn expansion_2() { + let mut rng = rand::thread_rng(); + let i = rng.gen_range(1..SIZES.0); + TEST_DB + .run_script( + "?[to] := *friends{fr: $id, to: a}, *friends{fr: a, to}", + BTreeMap::from([("id".to_string(), json!(i))]), + ) + .unwrap(); +} + +fn expansion_2_filter() { + let mut rng = rand::thread_rng(); + let i = rng.gen_range(1..SIZES.0); + TEST_DB + .run_script( + "?[to] := *friends{fr: $id, to: a}, *friends{fr: a, to}, *user{uid: to, age}, try(age >= 18, false)", + BTreeMap::from([("id".to_string(), json!(i))]), + ) + .unwrap(); +} + +fn expansion_3() { + let mut rng = rand::thread_rng(); + let i = rng.gen_range(1..SIZES.0); + TEST_DB + .run_script( + r#" + l1[to] := *friends{fr: $id, to} + l2[to] := l1[fr], *friends{fr, to} + ?[to] := l2[fr], *friends{fr, to} + "#, + BTreeMap::from([("id".to_string(), json!(i))]), + ) + .unwrap(); +} + +fn expansion_3_filter() { + let i = rand::thread_rng().gen_range(1..SIZES.0); + TEST_DB + .run_script( + r#" + l1[to] := *friends{fr: $id, to} + l2[to] := l1[fr], *friends{fr, to} + ?[to] := l2[fr], *friends{fr, to}, *user{uid: to, age}, try(age >= 18, false) + "#, + BTreeMap::from([("id".to_string(), json!(i))]), + ) + .unwrap(); +} + +fn expansion_4() { + let i = rand::thread_rng().gen_range(1..SIZES.0); + TEST_DB + .run_script( + r#" + l1[to] := *friends{fr: $id, to} + l2[to] := l1[fr], *friends{fr, to} + l3[to] := l2[fr], *friends{fr, to} + ?[to] := l3[fr], *friends{fr, to} + "#, + BTreeMap::from([("id".to_string(), json!(i))]), + ) + .unwrap(); +} + +fn expansion_4_filter() { + let i = rand::thread_rng().gen_range(1..SIZES.0); + TEST_DB + .run_script( + r#" + l1[to] := *friends{fr: $id, to} + l2[to] := l1[fr], *friends{fr, to} + l3[to] := l2[fr], *friends{fr, to} + ?[to] := l3[fr], *friends{fr, to} + "#, + BTreeMap::from([("id".to_string(), json!(i))]), + ) + .unwrap(); +} + +fn neighbours_2() { + let mut rng = rand::thread_rng(); + let i = rng.gen_range(1..SIZES.0); + TEST_DB + .run_script( + r#" + l1[to] := *friends{fr: $id, to} + ?[to] := l1[to] + ?[to] := l1[fr], *friends{fr, to} + "#, + BTreeMap::from([("id".to_string(), json!(i))]), + ) + .unwrap(); +} + +fn neighbours_2_filter() { + let mut rng = rand::thread_rng(); + let i = rng.gen_range(1..SIZES.0); + TEST_DB + .run_script( + r#" + l1[to] := *friends{fr: $id, to} + l2[to] := l1[to] + l2[to] := l1[fr], *friends{fr, to} + ?[to] := l2[to], *user{uid: to, age}, try(age >= 18, false) + "#, + BTreeMap::from([("id".to_string(), json!(i))]), + ) + .unwrap(); +} + +fn neighbours_2_data() { + let mut rng = rand::thread_rng(); + let i = rng.gen_range(1..SIZES.0); + TEST_DB + .run_script( + r#" + l1[to] := *friends{fr: $id, to} + l2[to] := l1[to] + l2[to] := l1[fr], *friends{fr, to} + ?[to, age, cmpl_pct, gender] := l2[to], *user{uid: to, age, cmpl_pct, gender} + "#, + BTreeMap::from([("id".to_string(), json!(i))]), + ) + .unwrap(); +} + +fn neighbours_2_filter_data() { + let mut rng = rand::thread_rng(); + let i = rng.gen_range(1..SIZES.0); + TEST_DB + .run_script( + r#" + l1[to] := *friends{fr: $id, to} + l2[to] := l1[to] + l2[to] := l1[fr], *friends{fr, to} + ?[to, age, cmpl_pct, gender] := l2[to], *user{uid: to, age, cmpl_pct, gender}, try(age >= 18, false) + "#, + BTreeMap::from([("id".to_string(), json!(i))]), + ) + .unwrap(); +} + +fn pattern_cycle() { + let mut rng = rand::thread_rng(); + let i = rng.gen_range(1..SIZES.0); + TEST_DB + .run_script( + r#" + ?[n, m] := n = $id, *friends{fr: n, to: m}, *friends.rev{fr: m, to: n} + "#, + BTreeMap::from([("id".to_string(), json!(i))]), + ) + .unwrap(); +} + +fn pattern_long() { + let mut rng = rand::thread_rng(); + let i = rng.gen_range(1..SIZES.0); + TEST_DB + .run_script( + r#" + ?[n] := *friends{fr: $id, to: n2}, + *friends{fr: n2, to: n3}, + *friends{fr: n3, to: n4}, + *friends.rev{to: n4, fr: n} + + :limit 1 + "#, + BTreeMap::from([("id".to_string(), json!(i))]), + ) + .unwrap(); +} + +fn pattern_short() { + let mut rng = rand::thread_rng(); + let i = rng.gen_range(1..SIZES.0); + TEST_DB + .run_script( + r#" + ?[to] := *friends{fr: $id, to} + + :limit 1 + "#, + BTreeMap::from([("id".to_string(), json!(i))]), + ) + .unwrap(); +} + +#[bench] +fn bench_aggregation(b: &mut Bencher) { + initialize(&TEST_DB); + b.iter(aggregation) +} + +#[bench] +fn bench_aggregation_distinct(b: &mut Bencher) { + initialize(&TEST_DB); + b.iter(aggregation_distinct) +} + +#[bench] +fn bench_aggregation_filter(b: &mut Bencher) { + initialize(&TEST_DB); + b.iter(aggregation_filter) +} + +#[bench] +fn bench_min_max(b: &mut Bencher) { + initialize(&TEST_DB); + b.iter(min_max) +} + +#[bench] +fn bench_expansion_1(b: &mut Bencher) { + initialize(&TEST_DB); + b.iter(expansion_1) +} + +#[bench] +fn bench_expansion_1_filter(b: &mut Bencher) { + initialize(&TEST_DB); + b.iter(expansion_1_filter) +} + +#[bench] +fn bench_expansion_2(b: &mut Bencher) { + initialize(&TEST_DB); + b.iter(expansion_2) +} + +#[bench] +fn bench_expansion_2_filter(b: &mut Bencher) { + initialize(&TEST_DB); + b.iter(expansion_2_filter) +} + +#[bench] +fn bench_expansion_3(b: &mut Bencher) { + initialize(&TEST_DB); + b.iter(expansion_3) +} + +#[bench] +fn bench_expansion_3_filter(b: &mut Bencher) { + initialize(&TEST_DB); + b.iter(expansion_3_filter) +} + +#[bench] +fn bench_expansion_4(b: &mut Bencher) { + initialize(&TEST_DB); + b.iter(expansion_4) +} + +#[bench] +fn bench_expansion_4_filter(b: &mut Bencher) { + initialize(&TEST_DB); + b.iter(expansion_4_filter) +} + +#[bench] +fn bench_neighbours_2(b: &mut Bencher) { + initialize(&TEST_DB); + b.iter(neighbours_2) +} + +#[bench] +fn bench_neighbours_2_filter(b: &mut Bencher) { + initialize(&TEST_DB); + b.iter(neighbours_2_filter) +} + +#[bench] +fn bench_neighbours_2_data(b: &mut Bencher) { + initialize(&TEST_DB); + b.iter(neighbours_2_data) +} + +#[bench] +fn bench_neighbours_2_filter_data(b: &mut Bencher) { + initialize(&TEST_DB); + b.iter(neighbours_2_filter_data) +} + +#[bench] +fn bench_pattern_cycle(b: &mut Bencher) { + initialize(&TEST_DB); + b.iter(pattern_cycle) +} + +#[bench] +fn bench_pattern_long(b: &mut Bencher) { + initialize(&TEST_DB); + b.iter(pattern_long) +} +#[bench] +fn bench_pattern_short(b: &mut Bencher) { + initialize(&TEST_DB); + b.iter(pattern_short) +} + +#[bench] +fn bench_single_vertex(b: &mut Bencher) { + initialize(&TEST_DB); + b.iter(single_vertex) +} + +#[bench] +fn bench_single_vertex_write(b: &mut Bencher) { + initialize(&TEST_DB); + b.iter(single_vertex_write) +} + +#[bench] +fn bench_single_edge_write(b: &mut Bencher) { + initialize(&TEST_DB); + b.iter(single_edge_write) +} + +#[bench] +fn bench_single_vertex_update(b: &mut Bencher) { + initialize(&TEST_DB); + b.iter(single_vertex_update) +} + +#[bench] +fn throughput(_: &mut Bencher) { + use rayon::prelude::*; + + println!("throughput benchmarks"); + dbg!(rayon::current_num_threads()); + let init_time = Instant::now(); + initialize(&TEST_DB); + dbg!(init_time.elapsed()); + + let expansion_1_time = Instant::now(); + let mut count = 10000usize; + (0..count).into_par_iter().for_each(|_| { + expansion_1(); + }); + dbg!((count as f64) / expansion_1_time.elapsed().as_secs_f64()); + + let expansion_1_filter_time = Instant::now(); + (0..count).into_par_iter().for_each(|_| { + expansion_1_filter(); + }); + dbg!((count as f64) / expansion_1_filter_time.elapsed().as_secs_f64()); + + let expansion_2_time = Instant::now(); + count = 1000; + (0..count).into_par_iter().for_each(|_| { + expansion_2(); + }); + dbg!((count as f64) / expansion_2_time.elapsed().as_secs_f64()); + + let expansion_2_filter_time = Instant::now(); + (0..count).into_par_iter().for_each(|_| { + expansion_2_filter(); + }); + dbg!((count as f64) / expansion_2_filter_time.elapsed().as_secs_f64()); + + let expansion_3_time = Instant::now(); + count = 500; + (0..count).into_par_iter().for_each(|_| { + expansion_3(); + }); + dbg!((count as f64) / expansion_3_time.elapsed().as_secs_f64()); + + let expansion_3_filter_time = Instant::now(); + (0..count).into_par_iter().for_each(|_| { + expansion_3_filter(); + }); + dbg!((count as f64) / expansion_3_filter_time.elapsed().as_secs_f64()); + + let expansion_4_time = Instant::now(); + count = 50; + (0..count).into_par_iter().for_each(|_| { + expansion_4(); + }); + dbg!((count as f64) / expansion_4_time.elapsed().as_secs_f64()); + + let expansion_4_filter_time = Instant::now(); + (0..count).into_par_iter().for_each(|_| { + expansion_4_filter(); + }); + dbg!((count as f64) / expansion_4_filter_time.elapsed().as_secs_f64()); + + let neighbours_2_time = Instant::now(); + count = 5000; + (0..count).into_par_iter().for_each(|_| { + neighbours_2(); + }); + dbg!((count as f64) / neighbours_2_time.elapsed().as_secs_f64()); + + let neighbours_2_filter_time = Instant::now(); + count = 5000; + (0..count).into_par_iter().for_each(|_| { + neighbours_2_filter(); + }); + dbg!((count as f64) / neighbours_2_filter_time.elapsed().as_secs_f64()); + + let neighbours_2_data_time = Instant::now(); + count = 5000; + (0..count).into_par_iter().for_each(|_| { + neighbours_2_data(); + }); + dbg!((count as f64) / neighbours_2_data_time.elapsed().as_secs_f64()); + + let neighbours_2_filter_data_time = Instant::now(); + count = 5000; + (0..count).into_par_iter().for_each(|_| { + neighbours_2_filter_data(); + }); + dbg!((count as f64) / neighbours_2_filter_data_time.elapsed().as_secs_f64()); + + let pattern_cycle_time = Instant::now(); + count = 10000; + (0..count).into_par_iter().for_each(|_| { + pattern_cycle(); + }); + dbg!((count as f64) / pattern_cycle_time.elapsed().as_secs_f64()); + + let pattern_long_time = Instant::now(); + count = 10000; + (0..count).into_par_iter().for_each(|_| { + pattern_long(); + }); + dbg!((count as f64) / pattern_long_time.elapsed().as_secs_f64()); + + let pattern_short_time = Instant::now(); + count = 10000; + (0..count).into_par_iter().for_each(|_| { + pattern_short(); + }); + dbg!((count as f64) / pattern_short_time.elapsed().as_secs_f64()); + + let aggregation_time = Instant::now(); + count = 100; + (0..count).into_par_iter().for_each(|_| { + aggregation(); + }); + dbg!((count as f64) / aggregation_time.elapsed().as_secs_f64()); + + let aggregation_distinct_time = Instant::now(); + count = 100; + (0..count).into_par_iter().for_each(|_| { + aggregation_distinct(); + }); + dbg!((count as f64) / aggregation_distinct_time.elapsed().as_secs_f64()); + + let aggregation_filter_time = Instant::now(); + count = 100; + (0..count).into_par_iter().for_each(|_| { + aggregation_filter(); + }); + dbg!((count as f64) / aggregation_filter_time.elapsed().as_secs_f64()); + + let min_max_time = Instant::now(); + count = 100; + (0..count).into_par_iter().for_each(|_| { + min_max(); + }); + dbg!((count as f64) / min_max_time.elapsed().as_secs_f64()); + + let single_vertex_time = Instant::now(); + count = 10000; + (0..count).into_par_iter().for_each(|_| { + single_vertex(); + }); + dbg!((count as f64) / single_vertex_time.elapsed().as_secs_f64()); + + let single_vertex_write_time = Instant::now(); + count = 10000; + (0..count).into_par_iter().for_each(|_| { + single_vertex_write(); + }); + dbg!((count as f64) / single_vertex_write_time.elapsed().as_secs_f64()); + + let single_edge_write_time = Instant::now(); + count = 10000; + (0..count).into_par_iter().for_each(|_| { + single_edge_write(); + }); + dbg!((count as f64) / single_edge_write_time.elapsed().as_secs_f64()); + + let single_vertex_update_time = Instant::now(); + count = 10000; + (0..count).into_par_iter().for_each(|_| { + single_vertex_update(); + }); + dbg!((count as f64) / single_vertex_update_time.elapsed().as_secs_f64()); +} + +fn wrap(mixed_pct: f64, f: QueryFn) { + use rand::prelude::*; + + let mut gen = rand::thread_rng(); + if gen.gen_bool(mixed_pct) { + let wtr = WRITE_QUERIES.choose(&mut gen).unwrap(); + wtr(); + } else { + f(); + } +} + +#[bench] +fn realistic(_: &mut Bencher) { + use rand::prelude::*; + use rayon::prelude::*; + + println!("realistic benchmarks"); + dbg!(rayon::current_num_threads()); + let init_time = Instant::now(); + initialize(&TEST_DB); + dbg!(init_time.elapsed()); + + let percentages = [ + [0.2, 0.4, 0.1, 0.3], + [0.0, 0.7, 0.0, 0.3], + [0.0, 0.5, 0.0, 0.5], + [0.0, 0.3, 0.0, 0.7], + ]; + + for [analytical, read, update, write] in percentages { + dbg!((analytical, read, update, write)); + let count = if analytical > 0.0 { 1000 } else { 10000 }; + let taken = Instant::now(); + (0..count).into_par_iter().for_each(|_| { + let mut gen = thread_rng(); + let p = gen.gen::(); + let f = if p < analytical { + ANALYTICAL_QUERIES.choose(&mut gen) + } else if p < analytical + read { + READ_QUERIES.choose(&mut gen) + } else if p < analytical + read + update { + UPDATE_QUERIES.choose(&mut gen) + } else { + WRITE_QUERIES.choose(&mut gen) + }; + f.unwrap()() + }); + dbg!((count as f64) / taken.elapsed().as_secs_f64()); + } +} + +#[bench] +fn mixed(_: &mut Bencher) { + use rayon::prelude::*; + + println!("mixed benchmarks"); + dbg!(rayon::current_num_threads()); + let init_time = Instant::now(); + initialize(&TEST_DB); + dbg!(init_time.elapsed()); + + let mixed_pct = env::var("COZO_BENCH_POKEC_MIX_PCT").unwrap_or("0.3".to_string()); + let mixed_pct = mixed_pct.parse::().unwrap(); + dbg!(mixed_pct); + assert!(mixed_pct >= 0.); + assert!(mixed_pct <= 1.); + + let expansion_1_time = Instant::now(); + let mut count = 10000usize; + (0..count).into_par_iter().for_each(|_| { + wrap(mixed_pct, expansion_1); + }); + dbg!((count as f64) / expansion_1_time.elapsed().as_secs_f64()); + + let expansion_1_filter_time = Instant::now(); + (0..count).into_par_iter().for_each(|_| { + wrap(mixed_pct, expansion_1_filter); + }); + dbg!((count as f64) / expansion_1_filter_time.elapsed().as_secs_f64()); + + let expansion_2_time = Instant::now(); + count = 1000; + (0..count).into_par_iter().for_each(|_| { + wrap(mixed_pct, expansion_2); + }); + dbg!((count as f64) / expansion_2_time.elapsed().as_secs_f64()); + + let expansion_2_filter_time = Instant::now(); + (0..count).into_par_iter().for_each(|_| { + wrap(mixed_pct, expansion_2_filter); + }); + dbg!((count as f64) / expansion_2_filter_time.elapsed().as_secs_f64()); + + let expansion_3_time = Instant::now(); + count = 500; + (0..count).into_par_iter().for_each(|_| { + wrap(mixed_pct, expansion_3); + }); + dbg!((count as f64) / expansion_3_time.elapsed().as_secs_f64()); + + let expansion_3_filter_time = Instant::now(); + (0..count).into_par_iter().for_each(|_| { + wrap(mixed_pct, expansion_3_filter); + }); + dbg!((count as f64) / expansion_3_filter_time.elapsed().as_secs_f64()); + + let expansion_4_time = Instant::now(); + count = 50; + (0..count).into_par_iter().for_each(|_| { + wrap(mixed_pct, expansion_4); + }); + dbg!((count as f64) / expansion_4_time.elapsed().as_secs_f64()); + + let expansion_4_filter_time = Instant::now(); + (0..count).into_par_iter().for_each(|_| { + wrap(mixed_pct, expansion_4_filter); + }); + dbg!((count as f64) / expansion_4_filter_time.elapsed().as_secs_f64()); + + let neighbours_2_time = Instant::now(); + count = 5000; + (0..count).into_par_iter().for_each(|_| { + wrap(mixed_pct, neighbours_2); + }); + dbg!((count as f64) / neighbours_2_time.elapsed().as_secs_f64()); + + let neighbours_2_filter_time = Instant::now(); + count = 5000; + (0..count).into_par_iter().for_each(|_| { + wrap(mixed_pct, neighbours_2_filter); + }); + dbg!((count as f64) / neighbours_2_filter_time.elapsed().as_secs_f64()); + + let neighbours_2_data_time = Instant::now(); + count = 5000; + (0..count).into_par_iter().for_each(|_| { + wrap(mixed_pct, neighbours_2_data); + }); + dbg!((count as f64) / neighbours_2_data_time.elapsed().as_secs_f64()); + + let neighbours_2_filter_data_time = Instant::now(); + count = 5000; + (0..count).into_par_iter().for_each(|_| { + wrap(mixed_pct, neighbours_2_filter_data); + }); + dbg!((count as f64) / neighbours_2_filter_data_time.elapsed().as_secs_f64()); + + let pattern_cycle_time = Instant::now(); + count = 10000; + (0..count).into_par_iter().for_each(|_| { + wrap(mixed_pct, pattern_cycle); + }); + dbg!((count as f64) / pattern_cycle_time.elapsed().as_secs_f64()); + + let pattern_long_time = Instant::now(); + count = 10000; + (0..count).into_par_iter().for_each(|_| { + wrap(mixed_pct, pattern_long); + }); + dbg!((count as f64) / pattern_long_time.elapsed().as_secs_f64()); + + let pattern_short_time = Instant::now(); + count = 10000; + (0..count).into_par_iter().for_each(|_| { + wrap(mixed_pct, pattern_short); + }); + dbg!((count as f64) / pattern_short_time.elapsed().as_secs_f64()); + + let aggregation_time = Instant::now(); + count = 100; + (0..count).into_par_iter().for_each(|_| { + wrap(mixed_pct, aggregation); + }); + dbg!((count as f64) / aggregation_time.elapsed().as_secs_f64()); + + let aggregation_distinct_time = Instant::now(); + count = 100; + (0..count).into_par_iter().for_each(|_| { + wrap(mixed_pct, aggregation_distinct); + }); + dbg!((count as f64) / aggregation_distinct_time.elapsed().as_secs_f64()); + + let aggregation_filter_time = Instant::now(); + count = 100; + (0..count).into_par_iter().for_each(|_| { + wrap(mixed_pct, aggregation_filter); + }); + dbg!((count as f64) / aggregation_filter_time.elapsed().as_secs_f64()); + + let min_max_time = Instant::now(); + count = 100; + (0..count).into_par_iter().for_each(|_| { + wrap(mixed_pct, min_max); + }); + dbg!((count as f64) / min_max_time.elapsed().as_secs_f64()); + + let single_vertex_time = Instant::now(); + count = 10000; + (0..count).into_par_iter().for_each(|_| { + wrap(mixed_pct, single_vertex); + }); + dbg!((count as f64) / single_vertex_time.elapsed().as_secs_f64()); + + let single_vertex_write_time = Instant::now(); + count = 10000; + (0..count).into_par_iter().for_each(|_| { + wrap(mixed_pct, single_vertex_write); + }); + dbg!((count as f64) / single_vertex_write_time.elapsed().as_secs_f64()); + + let single_edge_write_time = Instant::now(); + count = 10000; + (0..count).into_par_iter().for_each(|_| { + wrap(mixed_pct, single_edge_write); + }); + dbg!((count as f64) / single_edge_write_time.elapsed().as_secs_f64()); + + let single_vertex_update_time = Instant::now(); + count = 10000; + (0..count).into_par_iter().for_each(|_| { + wrap(mixed_pct, single_vertex_update); + }); + dbg!((count as f64) / single_vertex_update_time.elapsed().as_secs_f64()); +} diff --git a/cozo-core/tests/air_routes.rs b/cozo-core/tests/air_routes.rs index caade582..ed2c9d8e 100644 --- a/cozo-core/tests/air_routes.rs +++ b/cozo-core/tests/air_routes.rs @@ -13,7 +13,7 @@ use std::time::Instant; use approx::AbsDiffEq; use env_logger::Env; -use lazy_static::lazy_static; +use lazy_static::{initialize, lazy_static}; use serde_json::json; use cozo::DbInstance; @@ -157,15 +157,9 @@ lazy_static! { }; } -fn check_db() { - let _ = TEST_DB - .run_script("?[a] <- [[1]]", Default::default()) - .unwrap(); -} - #[test] fn dfs() { - check_db(); + initialize(&TEST_DB); let dfs = Instant::now(); let rows = TEST_DB .run_script( @@ -189,7 +183,7 @@ fn dfs() { #[test] fn empty() { - check_db(); + initialize(&TEST_DB); let res = TEST_DB.run_script( r#" ?[id, name] <- [[]] @@ -201,7 +195,7 @@ fn empty() { #[test] fn bfs() { - check_db(); + initialize(&TEST_DB); let bfs = Instant::now(); let rows = TEST_DB .run_script( @@ -226,7 +220,7 @@ fn bfs() { #[test] fn scc() { - check_db(); + initialize(&TEST_DB); let scc = Instant::now(); let _ = TEST_DB .run_script( @@ -236,13 +230,14 @@ fn scc() { "#, Default::default(), ) - .unwrap().rows; + .unwrap() + .rows; dbg!(scc.elapsed()); } #[test] fn cc() { - check_db(); + initialize(&TEST_DB); let cc = Instant::now(); let _ = TEST_DB .run_script( @@ -252,13 +247,14 @@ fn cc() { "#, Default::default(), ) - .unwrap().rows; + .unwrap() + .rows; dbg!(cc.elapsed()); } #[test] fn astar() { - check_db(); + initialize(&TEST_DB); let astar = Instant::now(); let _ = TEST_DB.run_script(r#" code_lat_lon[code, lat, lon] := *airport{code, lat, lon} @@ -271,7 +267,7 @@ fn astar() { #[test] fn deg_centrality() { - check_db(); + initialize(&TEST_DB); let deg_centrality = Instant::now(); TEST_DB .run_script( @@ -283,13 +279,14 @@ fn deg_centrality() { "#, Default::default(), ) - .unwrap().rows; + .unwrap() + .rows; dbg!(deg_centrality.elapsed()); } #[test] fn dijkstra() { - check_db(); + initialize(&TEST_DB); let dijkstra = Instant::now(); TEST_DB @@ -302,14 +299,15 @@ fn dijkstra() { "#, Default::default(), ) - .unwrap().rows; + .unwrap() + .rows; dbg!(dijkstra.elapsed()); } #[test] fn yen() { - check_db(); + initialize(&TEST_DB); let yen = Instant::now(); TEST_DB @@ -321,14 +319,15 @@ fn yen() { "#, Default::default(), ) - .unwrap().rows; + .unwrap() + .rows; dbg!(yen.elapsed()); } #[test] fn starts_with() { - check_db(); + initialize(&TEST_DB); let starts_with = Instant::now(); let rows = TEST_DB .run_script( @@ -360,7 +359,7 @@ fn starts_with() { #[test] fn range_check() { - check_db(); + initialize(&TEST_DB); let range_check = Instant::now(); let rows = TEST_DB @@ -380,7 +379,7 @@ fn range_check() { #[test] fn no_airports() { - check_db(); + initialize(&TEST_DB); let no_airports = Instant::now(); let rows = TEST_DB @@ -390,7 +389,8 @@ fn no_airports() { "#, Default::default(), ) - .unwrap().rows; + .unwrap() + .rows; assert_eq!( json!(rows), @@ -407,7 +407,7 @@ fn no_airports() { #[test] fn no_routes_airport() { - check_db(); + initialize(&TEST_DB); let no_routes_airports = Instant::now(); let rows = TEST_DB @@ -417,7 +417,8 @@ fn no_routes_airport() { "#, Default::default(), ) - .unwrap().rows; + .unwrap() + .rows; assert_eq!( json!(rows), @@ -435,7 +436,7 @@ fn no_routes_airport() { #[test] fn runway_distribution() { - check_db(); + initialize(&TEST_DB); let no_routes_airports = Instant::now(); let rows = TEST_DB @@ -445,7 +446,8 @@ fn runway_distribution() { "#, Default::default(), ) - .unwrap().rows; + .unwrap() + .rows; assert_eq!( json!(rows), @@ -464,7 +466,7 @@ fn runway_distribution() { #[test] fn most_out_routes() { - check_db(); + initialize(&TEST_DB); let most_out_routes = Instant::now(); let rows = TEST_DB @@ -476,7 +478,8 @@ fn most_out_routes() { "#, Default::default(), ) - .unwrap().rows; + .unwrap() + .rows; assert_eq!( json!(rows), @@ -496,7 +499,7 @@ fn most_out_routes() { #[test] fn most_out_routes_again() { - check_db(); + initialize(&TEST_DB); let most_out_routes_again = Instant::now(); let rows = TEST_DB @@ -508,7 +511,8 @@ fn most_out_routes_again() { "#, Default::default(), ) - .unwrap().rows; + .unwrap() + .rows; assert_eq!( json!(rows), @@ -528,7 +532,7 @@ fn most_out_routes_again() { #[test] fn most_routes() { - check_db(); + initialize(&TEST_DB); let most_routes = Instant::now(); let rows = TEST_DB @@ -541,7 +545,8 @@ fn most_routes() { "#, Default::default(), ) - .unwrap().rows; + .unwrap() + .rows; assert_eq!( json!(rows), @@ -559,7 +564,7 @@ fn most_routes() { #[test] fn airport_with_one_route() { - check_db(); + initialize(&TEST_DB); let airport_with_one_route = Instant::now(); let rows = TEST_DB @@ -570,7 +575,8 @@ fn airport_with_one_route() { "#, Default::default(), ) - .unwrap().rows; + .unwrap() + .rows; assert_eq!(json!(rows), json!([[777]])); dbg!(airport_with_one_route.elapsed()); @@ -578,7 +584,7 @@ fn airport_with_one_route() { #[test] fn single_runway_with_most_routes() { - check_db(); + initialize(&TEST_DB); let single_runway_with_most_routes = Instant::now(); let rows = TEST_DB @@ -594,7 +600,8 @@ fn single_runway_with_most_routes() { "#, Default::default(), ) - .unwrap().rows; + .unwrap() + .rows; assert_eq!( json!(rows), @@ -611,7 +618,7 @@ fn single_runway_with_most_routes() { #[test] fn most_routes_in_canada() { - check_db(); + initialize(&TEST_DB); let most_routes_in_canada = Instant::now(); let rows = TEST_DB @@ -625,7 +632,8 @@ fn most_routes_in_canada() { "#, Default::default(), ) - .unwrap().rows; + .unwrap() + .rows; assert_eq!( json!(rows), @@ -647,7 +655,7 @@ fn most_routes_in_canada() { #[test] fn uk_count() { - check_db(); + initialize(&TEST_DB); let uk_count = Instant::now(); let rows = TEST_DB @@ -657,7 +665,8 @@ fn uk_count() { "#, Default::default(), ) - .unwrap().rows; + .unwrap() + .rows; assert_eq!( json!(rows), @@ -668,7 +677,7 @@ fn uk_count() { #[test] fn airports_by_country() { - check_db(); + initialize(&TEST_DB); let airports_by_country = Instant::now(); let rows = TEST_DB @@ -682,7 +691,8 @@ fn airports_by_country() { "#, Default::default(), ) - .unwrap().rows; + .unwrap() + .rows; assert_eq!( json!(rows), @@ -721,7 +731,7 @@ fn airports_by_country() { #[test] fn n_airports_by_continent() { - check_db(); + initialize(&TEST_DB); let n_airports_by_continent = Instant::now(); let rows = TEST_DB @@ -733,7 +743,8 @@ fn n_airports_by_continent() { "#, Default::default(), ) - .unwrap().rows; + .unwrap() + .rows; assert_eq!( json!(rows), @@ -747,7 +758,7 @@ fn n_airports_by_continent() { #[test] fn routes_per_airport() { - check_db(); + initialize(&TEST_DB); let routes_per_airport = Instant::now(); let rows = TEST_DB @@ -758,7 +769,8 @@ fn routes_per_airport() { "#, Default::default(), ) - .unwrap().rows; + .unwrap() + .rows; assert_eq!( json!(rows), @@ -772,7 +784,7 @@ fn routes_per_airport() { #[test] fn airports_by_route_number() { - check_db(); + initialize(&TEST_DB); let airports_by_route_number = Instant::now(); let rows = TEST_DB @@ -783,7 +795,8 @@ fn airports_by_route_number() { "#, Default::default(), ) - .unwrap().rows; + .unwrap() + .rows; assert_eq!(json!(rows), json!([[106, ["TFS", "YVR"]]])); dbg!(airports_by_route_number.elapsed()); @@ -791,7 +804,7 @@ fn airports_by_route_number() { #[test] fn out_from_aus() { - check_db(); + initialize(&TEST_DB); let out_from_aus = Instant::now(); let rows = TEST_DB @@ -803,7 +816,8 @@ fn out_from_aus() { "#, Default::default(), ) - .unwrap().rows; + .unwrap() + .rows; assert_eq!( json!(rows), @@ -815,7 +829,7 @@ fn out_from_aus() { #[test] fn const_return() { - check_db(); + initialize(&TEST_DB); let const_return = Instant::now(); let rows = TEST_DB @@ -825,7 +839,8 @@ fn const_return() { "#, Default::default(), ) - .unwrap().rows; + .unwrap() + .rows; assert_eq!(json!(rows), json!([["OK", 4]])); dbg!(const_return.elapsed()); @@ -833,7 +848,7 @@ fn const_return() { #[test] fn multi_res() { - check_db(); + initialize(&TEST_DB); let multi_res = Instant::now(); let rows = TEST_DB @@ -850,7 +865,8 @@ fn multi_res() { "#, Default::default(), ) - .unwrap().rows; + .unwrap() + .rows; assert_eq!( json!(rows), @@ -861,7 +877,7 @@ fn multi_res() { #[test] fn multi_unification() { - check_db(); + initialize(&TEST_DB); let multi_unification = Instant::now(); let rows = TEST_DB @@ -872,7 +888,8 @@ fn multi_unification() { "#, Default::default(), ) - .unwrap().rows; + .unwrap() + .rows; assert_eq!( json!(rows), @@ -884,7 +901,7 @@ fn multi_unification() { #[test] fn num_routes_from_eu_to_us() { - check_db(); + initialize(&TEST_DB); let num_routes_from_eu_to_us = Instant::now(); let rows = TEST_DB @@ -898,7 +915,8 @@ fn num_routes_from_eu_to_us() { "#, Default::default(), ) - .unwrap().rows; + .unwrap() + .rows; assert_eq!(json!(rows), json!([[435]])); dbg!(num_routes_from_eu_to_us.elapsed()); @@ -906,7 +924,7 @@ fn num_routes_from_eu_to_us() { #[test] fn num_airports_in_us_with_routes_from_eu() { - check_db(); + initialize(&TEST_DB); let num_airports_in_us_with_routes_from_eu = Instant::now(); let rows = TEST_DB @@ -918,7 +936,8 @@ fn num_airports_in_us_with_routes_from_eu() { "#, Default::default(), ) - .unwrap().rows; + .unwrap() + .rows; assert_eq!(json!(rows), json!([[45]])); dbg!(num_airports_in_us_with_routes_from_eu.elapsed()); @@ -926,7 +945,7 @@ fn num_airports_in_us_with_routes_from_eu() { #[test] fn num_routes_in_us_airports_from_eu() { - check_db(); + initialize(&TEST_DB); let num_routes_in_us_airports_from_eu = Instant::now(); let rows = TEST_DB @@ -937,7 +956,8 @@ fn num_routes_in_us_airports_from_eu() { "#, Default::default(), ) - .unwrap().rows; + .unwrap() + .rows; assert_eq!( json!(rows), @@ -957,7 +977,7 @@ fn num_routes_in_us_airports_from_eu() { #[test] fn routes_from_eu_to_us_starting_with_l() { - check_db(); + initialize(&TEST_DB); let routes_from_eu_to_us_starting_with_l = Instant::now(); let rows = TEST_DB @@ -970,7 +990,8 @@ fn routes_from_eu_to_us_starting_with_l() { "#, Default::default(), ) - .unwrap().rows; + .unwrap() + .rows; assert_eq!( json!(rows), @@ -994,7 +1015,7 @@ fn routes_from_eu_to_us_starting_with_l() { #[test] fn len_of_names_count() { - check_db(); + initialize(&TEST_DB); let len_of_names_count = Instant::now(); let rows = TEST_DB @@ -1006,15 +1027,19 @@ fn len_of_names_count() { "#, Default::default(), ) - .unwrap().rows; + .unwrap() + .rows; - assert_eq!(json!(rows), serde_json::Value::from_str(r#"[[891.0]]"#).unwrap()); + assert_eq!( + json!(rows), + serde_json::Value::from_str(r#"[[891.0]]"#).unwrap() + ); dbg!(len_of_names_count.elapsed()); } #[test] fn group_count_by_out() { - check_db(); + initialize(&TEST_DB); let group_count_by_out = Instant::now(); let rows = TEST_DB @@ -1029,7 +1054,8 @@ fn group_count_by_out() { "#, Default::default(), ) - .unwrap().rows; + .unwrap() + .rows; assert_eq!( json!(rows), @@ -1043,7 +1069,7 @@ fn group_count_by_out() { #[test] fn mean_group_count() { - check_db(); + initialize(&TEST_DB); let mean_group_count = Instant::now(); let rows = TEST_DB @@ -1055,7 +1081,8 @@ fn mean_group_count() { "#, Default::default(), ) - .unwrap().rows; + .unwrap() + .rows; let v = rows.get(0).unwrap().get(0).unwrap().as_f64().unwrap(); @@ -1065,7 +1092,7 @@ fn mean_group_count() { #[test] fn n_routes_from_london_uk() { - check_db(); + initialize(&TEST_DB); let n_routes_from_london_uk = Instant::now(); let rows = TEST_DB @@ -1075,7 +1102,8 @@ fn n_routes_from_london_uk() { "#, Default::default(), ) - .unwrap().rows; + .unwrap() + .rows; assert_eq!( json!(rows), @@ -1089,7 +1117,7 @@ fn n_routes_from_london_uk() { #[test] fn reachable_from_london_uk_in_two_hops() { - check_db(); + initialize(&TEST_DB); let reachable_from_london_uk_in_two_hops = Instant::now(); let rows = TEST_DB @@ -1101,7 +1129,8 @@ fn reachable_from_london_uk_in_two_hops() { "#, Default::default(), ) - .unwrap().rows; + .unwrap() + .rows; assert_eq!(json!(rows), json!([[2353]])); dbg!(reachable_from_london_uk_in_two_hops.elapsed()); @@ -1109,7 +1138,7 @@ fn reachable_from_london_uk_in_two_hops() { #[test] fn routes_within_england() { - check_db(); + initialize(&TEST_DB); let routes_within_england = Instant::now(); let rows = TEST_DB @@ -1120,7 +1149,8 @@ fn routes_within_england() { "#, Default::default(), ) - .unwrap().rows; + .unwrap() + .rows; assert_eq!( json!(rows), @@ -1143,7 +1173,7 @@ fn routes_within_england() { #[test] fn routes_within_england_time_no_dup() { - check_db(); + initialize(&TEST_DB); let routes_within_england_time_no_dup = Instant::now(); let rows = TEST_DB @@ -1154,7 +1184,8 @@ fn routes_within_england_time_no_dup() { "#, Default::default(), ) - .unwrap().rows; + .unwrap() + .rows; assert_eq!( json!(rows), @@ -1174,7 +1205,7 @@ fn routes_within_england_time_no_dup() { #[test] fn hard_route_finding() { - check_db(); + initialize(&TEST_DB); let hard_route_finding = Instant::now(); let rows = TEST_DB @@ -1189,7 +1220,8 @@ fn hard_route_finding() { "#, Default::default(), ) - .unwrap().rows; + .unwrap() + .rows; assert_eq!( json!(rows), @@ -1203,7 +1235,7 @@ fn hard_route_finding() { #[test] fn na_from_india() { - check_db(); + initialize(&TEST_DB); let na_from_india = Instant::now(); let rows = TEST_DB @@ -1216,7 +1248,8 @@ fn na_from_india() { "#, Default::default(), ) - .unwrap().rows; + .unwrap() + .rows; assert_eq!( json!(rows), @@ -1233,7 +1266,7 @@ fn na_from_india() { #[test] fn eu_cities_reachable_from_fll() { - check_db(); + initialize(&TEST_DB); let eu_cities_reachable_from_fll = Instant::now(); let rows = TEST_DB @@ -1243,7 +1276,8 @@ fn eu_cities_reachable_from_fll() { "#, Default::default(), ) - .unwrap().rows; + .unwrap() + .rows; assert_eq!( json!(rows), @@ -1259,7 +1293,7 @@ fn eu_cities_reachable_from_fll() { #[test] fn clt_to_eu_or_sa() { - check_db(); + initialize(&TEST_DB); let clt_to_eu_or_sa = Instant::now(); let rows = TEST_DB @@ -1269,7 +1303,8 @@ fn clt_to_eu_or_sa() { "#, Default::default(), ) - .unwrap().rows; + .unwrap() + .rows; assert_eq!( json!(rows), @@ -1285,7 +1320,7 @@ fn clt_to_eu_or_sa() { #[test] fn london_to_us() { - check_db(); + initialize(&TEST_DB); let london_to_us = Instant::now(); let rows = TEST_DB @@ -1296,7 +1331,8 @@ fn london_to_us() { "#, Default::default(), ) - .unwrap().rows; + .unwrap() + .rows; assert_eq!( json!(rows), @@ -1319,7 +1355,7 @@ fn london_to_us() { #[test] fn tx_to_ny() { - check_db(); + initialize(&TEST_DB); let tx_to_ny = Instant::now(); let rows = TEST_DB @@ -1330,7 +1366,8 @@ fn tx_to_ny() { "#, Default::default(), ) - .unwrap().rows; + .unwrap() + .rows; assert_eq!( json!(rows), @@ -1348,7 +1385,7 @@ fn tx_to_ny() { #[test] fn denver_to_mexico() { - check_db(); + initialize(&TEST_DB); let denver_to_mexico = Instant::now(); let rows = TEST_DB @@ -1358,7 +1395,8 @@ fn denver_to_mexico() { "#, Default::default(), ) - .unwrap().rows; + .unwrap() + .rows; assert_eq!( json!(rows), @@ -1375,7 +1413,7 @@ fn denver_to_mexico() { #[test] fn three_cities() { - check_db(); + initialize(&TEST_DB); let three_cities = Instant::now(); let rows = TEST_DB @@ -1386,7 +1424,8 @@ fn three_cities() { "#, Default::default(), ) - .unwrap().rows; + .unwrap() + .rows; assert_eq!( json!(rows), @@ -1406,7 +1445,7 @@ fn three_cities() { #[test] fn long_distance_from_lgw() { - check_db(); + initialize(&TEST_DB); let long_distance_from_lgw = Instant::now(); let rows = TEST_DB @@ -1417,7 +1456,8 @@ fn long_distance_from_lgw() { "#, Default::default(), ) - .unwrap().rows; + .unwrap() + .rows; assert_eq!( json!(rows), @@ -1441,7 +1481,7 @@ fn long_distance_from_lgw() { #[test] fn long_routes_one_dir() { - check_db(); + initialize(&TEST_DB); let long_routes_one_dir = Instant::now(); let rows = TEST_DB @@ -1451,7 +1491,8 @@ fn long_routes_one_dir() { "#, Default::default(), ) - .unwrap().rows; + .unwrap() + .rows; assert_eq!( json!(rows), @@ -1473,7 +1514,7 @@ fn long_routes_one_dir() { #[test] fn longest_routes() { - check_db(); + initialize(&TEST_DB); let longest_routes = Instant::now(); let rows = TEST_DB @@ -1485,7 +1526,8 @@ fn longest_routes() { "#, Default::default(), ) - .unwrap().rows; + .unwrap() + .rows; assert_eq!( json!(rows), @@ -1504,7 +1546,7 @@ fn longest_routes() { #[test] fn longest_routes_from_each_airports() { - check_db(); + initialize(&TEST_DB); let longest_routes_from_each_airports = Instant::now(); let rows = TEST_DB @@ -1515,7 +1557,8 @@ fn longest_routes_from_each_airports() { "#, Default::default(), ) - .unwrap().rows; + .unwrap() + .rows; assert_eq!( json!(rows), @@ -1532,7 +1575,7 @@ fn longest_routes_from_each_airports() { #[test] fn total_distance_from_three_cities() { - check_db(); + initialize(&TEST_DB); let total_distance_from_three_cities = Instant::now(); let rows = TEST_DB @@ -1543,7 +1586,8 @@ fn total_distance_from_three_cities() { "#, Default::default(), ) - .unwrap().rows; + .unwrap() + .rows; assert_eq!( json!(rows), @@ -1554,7 +1598,7 @@ fn total_distance_from_three_cities() { #[test] fn total_distance_within_three_cities() { - check_db(); + initialize(&TEST_DB); let total_distance_within_three_cities = Instant::now(); let rows = TEST_DB @@ -1565,7 +1609,8 @@ fn total_distance_within_three_cities() { "#, Default::default(), ) - .unwrap().rows; + .unwrap() + .rows; assert_eq!( json!(rows), @@ -1576,7 +1621,7 @@ fn total_distance_within_three_cities() { #[test] fn specific_distance() { - check_db(); + initialize(&TEST_DB); let specific_distance = Instant::now(); let rows = TEST_DB @@ -1586,15 +1631,19 @@ fn specific_distance() { "#, Default::default(), ) - .unwrap().rows; + .unwrap() + .rows; - assert_eq!(json!(rows), serde_json::Value::from_str(r#"[[748.0]]"#).unwrap()); + assert_eq!( + json!(rows), + serde_json::Value::from_str(r#"[[748.0]]"#).unwrap() + ); dbg!(specific_distance.elapsed()); } #[test] fn n_routes_between() { - check_db(); + initialize(&TEST_DB); let n_routes_between = Instant::now(); let rows = TEST_DB @@ -1606,15 +1655,19 @@ fn n_routes_between() { "#, Default::default(), ) - .unwrap().rows; + .unwrap() + .rows; - assert_eq!(json!(rows), serde_json::Value::from_str(r#"[[597]]"#).unwrap()); + assert_eq!( + json!(rows), + serde_json::Value::from_str(r#"[[597]]"#).unwrap() + ); dbg!(n_routes_between.elapsed()); } #[test] fn one_stop_distance() { - check_db(); + initialize(&TEST_DB); let one_stop_distance = Instant::now(); let rows = TEST_DB @@ -1628,7 +1681,8 @@ fn one_stop_distance() { "#, Default::default(), ) - .unwrap().rows; + .unwrap() + .rows; assert_eq!( json!(rows), @@ -1644,7 +1698,7 @@ fn one_stop_distance() { #[test] fn airport_most_routes() { - check_db(); + initialize(&TEST_DB); let airport_most_routes = Instant::now(); let rows = TEST_DB @@ -1656,7 +1710,8 @@ fn airport_most_routes() { "#, Default::default(), ) - .unwrap().rows; + .unwrap() + .rows; assert_eq!( json!(rows), @@ -1672,7 +1727,7 @@ fn airport_most_routes() { #[test] fn north_of_77() { - check_db(); + initialize(&TEST_DB); let north_of_77 = Instant::now(); let rows = TEST_DB @@ -1682,7 +1737,8 @@ fn north_of_77() { "#, Default::default(), ) - .unwrap().rows; + .unwrap() + .rows; assert_eq!( json!(rows), @@ -1693,7 +1749,7 @@ fn north_of_77() { #[test] fn greenwich_meridian() { - check_db(); + initialize(&TEST_DB); let greenwich_meridian = Instant::now(); let rows = TEST_DB @@ -1703,7 +1759,8 @@ fn greenwich_meridian() { "#, Default::default(), ) - .unwrap().rows; + .unwrap() + .rows; assert_eq!( json!(rows), @@ -1714,7 +1771,7 @@ fn greenwich_meridian() { #[test] fn box_around_heathrow() { - check_db(); + initialize(&TEST_DB); let box_around_heathrow = Instant::now(); let rows = TEST_DB @@ -1726,7 +1783,8 @@ fn box_around_heathrow() { "#, Default::default(), ) - .unwrap().rows; + .unwrap() + .rows; assert_eq!( json!(rows), @@ -1738,7 +1796,7 @@ fn box_around_heathrow() { #[test] fn dfw_by_region() { - check_db(); + initialize(&TEST_DB); let dfw_by_region = Instant::now(); let rows = TEST_DB @@ -1750,7 +1808,8 @@ fn dfw_by_region() { "#, Default::default(), ) - .unwrap().rows; + .unwrap() + .rows; assert_eq!( json!(rows), @@ -1769,7 +1828,7 @@ fn dfw_by_region() { #[test] fn great_circle_distance() { - check_db(); + initialize(&TEST_DB); let great_circle_distance = Instant::now(); let rows = TEST_DB @@ -1781,15 +1840,19 @@ fn great_circle_distance() { "#, Default::default(), ) - .unwrap().rows; + .unwrap() + .rows; - assert_eq!(json!(rows), serde_json::Value::from_str(r#"[[1.0]]"#).unwrap()); + assert_eq!( + json!(rows), + serde_json::Value::from_str(r#"[[1.0]]"#).unwrap() + ); dbg!(great_circle_distance.elapsed()); } #[test] fn aus_to_edi() { - check_db(); + initialize(&TEST_DB); let aus_to_edi = Instant::now(); let rows = TEST_DB @@ -1806,7 +1869,8 @@ fn aus_to_edi() { "#, Default::default(), ) - .unwrap().rows; + .unwrap() + .rows; assert_eq!( json!(rows), @@ -1817,7 +1881,7 @@ fn aus_to_edi() { #[test] fn reachable_from_lhr() { - check_db(); + initialize(&TEST_DB); let reachable_from_lhr = Instant::now(); let rows = TEST_DB @@ -1834,7 +1898,8 @@ fn reachable_from_lhr() { "#, Default::default(), ) - .unwrap().rows; + .unwrap() + .rows; assert_eq!( json!(rows), @@ -1859,7 +1924,7 @@ fn reachable_from_lhr() { #[test] fn furthest_from_lhr() { - check_db(); + initialize(&TEST_DB); let furthest_from_lhr = Instant::now(); let rows = TEST_DB @@ -1878,7 +1943,8 @@ fn furthest_from_lhr() { "#, Default::default(), ) - .unwrap().rows; + .unwrap() + .rows; assert_eq!( json!(rows), @@ -1898,7 +1964,7 @@ fn furthest_from_lhr() { #[test] fn skip_limit() { - check_db(); + initialize(&TEST_DB); let rows = TEST_DB .run_script( r#" @@ -1906,7 +1972,8 @@ fn skip_limit() { "#, Default::default(), ) - .unwrap().rows; + .unwrap() + .rows; assert_eq!(json!(rows), json!([[3], [4], [5], [6], [7], [8], [9]])); @@ -1917,7 +1984,8 @@ fn skip_limit() { "#, Default::default(), ) - .unwrap().rows; + .unwrap() + .rows; assert_eq!(json!(rows), json!([[3], [4], [5], [6], [7], [8], [9]])); @@ -1929,7 +1997,8 @@ fn skip_limit() { "#, Default::default(), ) - .unwrap().rows; + .unwrap() + .rows; assert_eq!(json!(rows), json!([[8], [9]])); @@ -1942,7 +2011,8 @@ fn skip_limit() { "#, Default::default(), ) - .unwrap().rows; + .unwrap() + .rows; assert_eq!(json!(rows), json!([[7], [8]])); @@ -1955,7 +2025,8 @@ fn skip_limit() { "#, Default::default(), ) - .unwrap().rows; + .unwrap() + .rows; assert_eq!(json!(rows), json!([[3], [4], [5], [6], [7], [8]])); }