use criterion::{BenchmarkId, criterion_group, criterion_main, Criterion}; use search_trees::bstree::BinarySearchTree; use search_trees::base::QueryableTree; use search_trees::avltree::AVLTree; use search_trees::rbtree::RedBlackTree; use rand::{rngs::StdRng, SeedableRng}; use rand::seq::{SliceRandom, IteratorRandom}; const TREE_SIZE: [i32; 5] = [10_000, 40_000, 70_000, 100_000, 130_000]; // const TREE_SIZE: [i32; 5] = [100, 400, 700, 1000, 1300]; fn benchmark_bst(tree_size: i32) { let mut bst = BinarySearchTree::new(); for v in 0..tree_size { bst.insert(v); } for v in 0..tree_size / 10 { bst.contains(v); } } fn benchmark_bst_insert_delete(tree_size: i32) { let seed = [0u8; 32]; let mut rng: StdRng = SeedableRng::from_seed(seed); let mut data: Vec = (0..tree_size).collect(); data.shuffle(&mut rng); let sample = data.iter().choose_multiple(&mut rng, (tree_size / 10) as usize); let mut bst = BinarySearchTree::new(); for v in &data { bst.insert(*v); } for v in sample.iter() { bst.delete(**v); } } fn benchmark_avl(tree_size: i32) { let mut avl = AVLTree::new(); for v in 0..tree_size { avl.insert(v); } for v in 0..tree_size / 10 { avl.contains(v); } } fn benchmark_avl_insert_delete(tree_size: i32) { let seed = [0u8; 32]; let mut rng: StdRng = SeedableRng::from_seed(seed); let mut data: Vec = (0..tree_size).collect(); data.shuffle(&mut rng); let sample = data.iter().choose_multiple(&mut rng, (tree_size / 10) as usize); let mut avl = AVLTree::new(); for v in &data { avl.insert(*v); } for v in sample.iter() { avl.delete(**v); } } fn benchmark_rbt(tree_size: i32) { let mut rbt = RedBlackTree::new(); for v in 0..tree_size { rbt.insert(v); } for v in 0..tree_size / 10 { rbt.contains(v); } } fn benchmark_rbt_insert_delete(tree_size: i32) { let seed = [0u8; 32]; let mut rng: StdRng = SeedableRng::from_seed(seed); let mut data: Vec = (0..tree_size).collect(); data.shuffle(&mut rng); let sample = data.iter().choose_multiple(&mut rng, (tree_size / 10) as usize); let mut rbt = RedBlackTree::new(); for v in &data { rbt.insert(*v); } for v in sample.iter() { rbt.delete(**v); } } fn bench_compare_all(c: &mut Criterion) { let mut group = c.benchmark_group("Compare_10Sample"); group.sample_size(10); for (idx, size) in TREE_SIZE.iter().enumerate() { group.bench_with_input( BenchmarkId::new("BST", idx), size, |b, i| b.iter(|| benchmark_bst(*i)) ); group.bench_with_input( BenchmarkId::new("AVL", idx), size, |b, i| b.iter(|| benchmark_avl(*i)) ); group.bench_with_input( BenchmarkId::new("RBT", idx), size, |b, i| { b.iter(|| benchmark_rbt(*i)); } ); } group.finish(); } fn bench_compare(c: &mut Criterion) { let mut group = c.benchmark_group("Compare"); for (idx, size) in TREE_SIZE.iter().enumerate() { group.bench_with_input( BenchmarkId::new("AVL", idx), size, |b, i| b.iter(|| benchmark_avl(*i)) ); group.bench_with_input( BenchmarkId::new("RBT", idx), size, |b, i| { b.iter(|| benchmark_rbt(*i)); } ); } group.finish(); } fn bench_compare_insert_delete(c: &mut Criterion) { let mut group = c.benchmark_group("Compare_insert_delete"); for (idx, size) in TREE_SIZE.iter().enumerate() { group.bench_with_input( BenchmarkId::new("BST", idx), size, |b, i| b.iter(|| benchmark_bst_insert_delete(*i)) ); group.bench_with_input( BenchmarkId::new("AVL", idx), size, |b, i| b.iter(|| benchmark_avl_insert_delete(*i)) ); group.bench_with_input( BenchmarkId::new("RBT", idx), size, |b, i| { b.iter(|| benchmark_rbt_insert_delete(*i)); } ); } group.finish(); } criterion_group!( benches, bench_compare_all, bench_compare, bench_compare_insert_delete, ); criterion_main!(benches);