diff --git a/.github/workflows/codspeed.yml b/.github/workflows/codspeed.yml new file mode 100644 index 0000000..27c3854 --- /dev/null +++ b/.github/workflows/codspeed.yml @@ -0,0 +1,28 @@ +name: codspeed-benchmarks + +on: + # Run on pushes to the main branch + push: + branches: + - "main" + # Run on pull requests + pull_request: + # `workflow_dispatch` allows CodSpeed to trigger backtest + # performance analysis in order to generate initial data. + workflow_dispatch: + +jobs: + benchmarks: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions-rust-lang/setup-rust-toolchain@v1 + + - name: Build the benchmark target(s) + run: cargo codspeed build + + - name: Run the benchmarks + uses: CodSpeedHQ/action@v2 + with: + run: cargo codspeed run + token: ${{ secrets.CODSPEED_TOKEN }} diff --git a/Cargo.toml b/Cargo.toml index 3810565..e3e305f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,3 +20,11 @@ default = ["serde"] debug = 2 codegen-units = 1 lto = true + +[dev-dependencies] +bencher = "0.1.5" +codspeed-bencher-compat = "2.6.0" + +[[bench]] +name = "bench" +harness = false diff --git a/benches/bench.rs b/benches/bench.rs index fa09f13..ba8cf73 100644 --- a/benches/bench.rs +++ b/benches/bench.rs @@ -1,9 +1,6 @@ //! A simple benchmark for flatcontainer, adopted from `columnation`'s benchmark. -#![feature(test)] - -extern crate test; - +use codspeed_bencher_compat::{benchmark_group, benchmark_main, Bencher}; use flatcontainer::impls::deduplicate::{CollapseSequence, ConsecutiveIndexPairs}; use flatcontainer::impls::index::IndexOptimized; use flatcontainer::impls::tuple::{TupleABCRegion, TupleABRegion}; @@ -11,44 +8,34 @@ use flatcontainer::{ ColumnsRegion, FlatStack, MirrorRegion, OwnedRegion, Push, Region, RegionPreference, ReserveItems, SliceRegion, StringRegion, }; -use test::Bencher; -#[bench] fn empty_copy(bencher: &mut Bencher) { _bench_copy(bencher, vec![(); 1024]); } -#[bench] fn u64_copy(bencher: &mut Bencher) { _bench_copy(bencher, vec![0u64; 1024]); } -#[bench] fn u32x2_copy(bencher: &mut Bencher) { _bench_copy(bencher, vec![(0u32, 0u32); 1024]); } -#[bench] fn u8_u64_copy(bencher: &mut Bencher) { _bench_copy(bencher, vec![(0u8, 0u64); 512]); } -#[bench] fn str10_copy(bencher: &mut Bencher) { _bench_copy(bencher, vec!["grawwwwrr!"; 1024]); } -#[bench] fn string10_copy(bencher: &mut Bencher) { _bench_copy(bencher, vec![format!("grawwwwrr!"); 1024]); } -#[bench] fn string20_copy(bencher: &mut Bencher) { _bench_copy(bencher, vec![format!("grawwwwrr!!!!!!!!!!!"); 512]); } -#[bench] fn vec_u_s_copy(bencher: &mut Bencher) { _bench_copy( bencher, vec![vec![(0u64, "grawwwwrr!".to_string()); 32]; 32], ); } -#[bench] fn vec_u_vn_s_copy(bencher: &mut Bencher) { _bench_copy( bencher, @@ -56,56 +43,45 @@ fn vec_u_vn_s_copy(bencher: &mut Bencher) { ); } -#[bench] fn empty_copy_region(bencher: &mut Bencher) { _bench_copy_region::, _>(bencher, vec![(); 1024]); } -#[bench] fn u64_copy_region(bencher: &mut Bencher) { _bench_copy_region::, _>(bencher, vec![0u64; 1024]); } -#[bench] fn u32x2_copy_region(bencher: &mut Bencher) { _bench_copy_region::, _>(bencher, vec![(0u32, 0u32); 1024]); } -#[bench] fn u8_u64_copy_region(bencher: &mut Bencher) { _bench_copy_region::, _>(bencher, vec![(0u8, 0u64); 512]); } -#[bench] fn str10_copy_region(bencher: &mut Bencher) { _bench_copy_region::, _>(bencher, vec!["grawwwwrr!"; 1024]); } -#[bench] fn str100_copy_region(bencher: &mut Bencher) { _bench_copy_region::, _>(bencher, vec!["grawwwwrrgrawwwwrrgrawwwwrrgrawwwwrrgrawwwwrrgrawwwwrrgrawwwwrrgrawwwwrrgrawwwwrr!!!!!!!!!grawwwwrr!"; 1024]); } -#[bench] fn string10_copy_region(bencher: &mut Bencher) { _bench_copy_region::, _>(bencher, vec![format!("grawwwwrr!"); 1024]); } -#[bench] fn string10_copy_region_collapse(bencher: &mut Bencher) { _bench_copy_region::< SliceRegion>, IndexOptimized>, _, >(bencher, vec![format!("grawwwwrr!"); 1024]); } -#[bench] fn string20_copy_region(bencher: &mut Bencher) { _bench_copy_region::, _>( bencher, vec![format!("grawwwwrr!!!!!!!!!!!"); 512], ); } -#[bench] fn vec_u_s_copy_region(bencher: &mut Bencher) { _bench_copy_region::, StringRegion>>>, _>( bencher, vec![vec![(0u64, "grawwwwrr!".to_string()); 32]; 32], ); } -#[bench] fn vec_u_vn_s_copy_region(bencher: &mut Bencher) { _bench_copy_region::< SliceRegion, OwnedRegion<_>, StringRegion>>>, @@ -115,7 +91,6 @@ fn vec_u_vn_s_copy_region(bencher: &mut Bencher) { vec![vec![(0u64, vec![(); 1 << 40], "grawwwwrr!".to_string()); 32]; 32], ); } -#[bench] fn vec_u_vn_s_copy_region_column(bencher: &mut Bencher) { _bench_copy_region::< SliceRegion< @@ -134,42 +109,33 @@ fn vec_u_vn_s_copy_region_column(bencher: &mut Bencher) { ); } -#[bench] fn empty_clone(bencher: &mut Bencher) { _bench_clone(bencher, vec![(); 1024]); } -#[bench] fn u64_clone(bencher: &mut Bencher) { _bench_clone(bencher, vec![0u64; 1024]); } -#[bench] fn u32x2_clone(bencher: &mut Bencher) { _bench_clone(bencher, vec![(0u32, 0u32); 1024]); } -#[bench] fn u8_u64_clone(bencher: &mut Bencher) { _bench_clone(bencher, vec![(0u8, 0u64); 512]); } -#[bench] fn str10_clone(bencher: &mut Bencher) { _bench_clone(bencher, vec!["grawwwwrr!"; 1024]); } -#[bench] fn string10_clone(bencher: &mut Bencher) { _bench_clone(bencher, vec![format!("grawwwwrr!"); 1024]); } -#[bench] fn string20_clone(bencher: &mut Bencher) { _bench_clone(bencher, vec![format!("grawwwwrr!!!!!!!!!!!"); 512]); } -#[bench] fn vec_u_s_clone(bencher: &mut Bencher) { _bench_clone( bencher, vec![vec![(0u64, "grawwwwrr!".to_string()); 32]; 32], ); } -#[bench] fn vec_u_vn_s_clone(bencher: &mut Bencher) { _bench_clone( bencher, @@ -177,42 +143,33 @@ fn vec_u_vn_s_clone(bencher: &mut Bencher) { ); } -#[bench] fn empty_realloc(bencher: &mut Bencher) { _bench_realloc(bencher, vec![(); 1024]); } -#[bench] fn u64_realloc(bencher: &mut Bencher) { _bench_realloc(bencher, vec![0u64; 1024]); } -#[bench] fn u32x2_realloc(bencher: &mut Bencher) { _bench_realloc(bencher, vec![(0u32, 0u32); 1024]); } -#[bench] fn u8_u64_realloc(bencher: &mut Bencher) { _bench_realloc(bencher, vec![(0u8, 0u64); 512]); } -#[bench] fn str10_realloc(bencher: &mut Bencher) { _bench_realloc(bencher, vec!["grawwwwrr!"; 1024]); } -#[bench] fn string10_realloc(bencher: &mut Bencher) { _bench_realloc(bencher, vec![format!("grawwwwrr!"); 1024]); } -#[bench] fn string20_realloc(bencher: &mut Bencher) { _bench_realloc(bencher, vec![format!("grawwwwrr!!!!!!!!!!!"); 512]); } -#[bench] fn vec_u_s_realloc(bencher: &mut Bencher) { _bench_realloc( bencher, vec![vec![(0u64, "grawwwwrr!".to_string()); 32]; 32], ); } -#[bench] fn vec_u_vn_s_realloc(bencher: &mut Bencher) { _bench_realloc( bencher, @@ -220,42 +177,33 @@ fn vec_u_vn_s_realloc(bencher: &mut Bencher) { ); } -#[bench] fn empty_prealloc(bencher: &mut Bencher) { _bench_prealloc(bencher, vec![(); 1024]); } -#[bench] fn u64_prealloc(bencher: &mut Bencher) { _bench_prealloc(bencher, vec![0u64; 1024]); } -#[bench] fn u32x2_prealloc(bencher: &mut Bencher) { _bench_prealloc(bencher, vec![(0u32, 0u32); 1024]); } -#[bench] fn u8_u64_prealloc(bencher: &mut Bencher) { _bench_prealloc(bencher, vec![(0u8, 0u64); 512]); } -#[bench] fn str10_prealloc(bencher: &mut Bencher) { _bench_prealloc(bencher, vec!["grawwwwrr!"; 1024]); } -#[bench] fn string10_prealloc(bencher: &mut Bencher) { _bench_prealloc(bencher, vec![format!("grawwwwrr!"); 1024]); } -#[bench] fn string20_prealloc(bencher: &mut Bencher) { _bench_prealloc(bencher, vec![format!("grawwwwrr!!!!!!!!!!!"); 512]); } -#[bench] fn vec_u_s_prealloc(bencher: &mut Bencher) { _bench_prealloc( bencher, vec![vec![(0u64, "grawwwwrr!".to_string()); 32]; 32], ); } -#[bench] fn vec_u_vn_s_prealloc(bencher: &mut Bencher) { _bench_prealloc( bencher, @@ -263,46 +211,36 @@ fn vec_u_vn_s_prealloc(bencher: &mut Bencher) { ); } -#[bench] fn empty_copy_flat(bencher: &mut Bencher) { _bench_copy_flat_preference(bencher, vec![(); 1024]); } -#[bench] fn u64_copy_flat(bencher: &mut Bencher) { _bench_copy_flat_preference(bencher, vec![0u64; 1024]); } -#[bench] fn u32x2_copy_flat(bencher: &mut Bencher) { _bench_copy_flat_preference(bencher, vec![(0u32, 0u32); 1024]); } -#[bench] fn u8_u64_copy_flat(bencher: &mut Bencher) { _bench_copy_flat_preference(bencher, vec![(0u8, 0u64); 512]); } -#[bench] fn str10_copy_flat(bencher: &mut Bencher) { _bench_copy_flat_preference(bencher, vec!["grawwwwrr!"; 1024]); } -#[bench] fn str100_copy_flat(bencher: &mut Bencher) { _bench_copy_flat_preference(bencher, vec!["grawwwwrrgrawwwwrrgrawwwwrrgrawwwwrrgrawwwwrrgrawwwwrrgrawwwwrrgrawwwwrrgrawwwwrr!!!!!!!!!grawwwwrr!"; 1024]); } -#[bench] fn string10_copy_flat(bencher: &mut Bencher) { _bench_copy_flat_preference(bencher, vec![format!("grawwwwrr!"); 1024]); } -#[bench] fn string20_copy_flat(bencher: &mut Bencher) { _bench_copy_flat_preference(bencher, vec![format!("grawwwwrr!!!!!!!!!!!"); 512]); } -#[bench] fn vec_u_s_copy_flat(bencher: &mut Bencher) { _bench_copy_flat_preference( bencher, vec![vec![(0u64, "grawwwwrr!".to_string()); 32]; 32], ); } -#[bench] fn vec_u_vn_s_copy_flat(bencher: &mut Bencher) { _bench_copy_flat_preference( bencher, @@ -310,49 +248,39 @@ fn vec_u_vn_s_copy_flat(bencher: &mut Bencher) { ); } -#[bench] fn empty_copy_flat_region(bencher: &mut Bencher) { _bench_copy_flat::, _>(bencher, vec![(); 1024]); } -#[bench] fn u64_copy_flat_region(bencher: &mut Bencher) { _bench_copy_flat::, _>(bencher, vec![0u64; 1024]); } -#[bench] fn u32x2_copy_flat_region(bencher: &mut Bencher) { _bench_copy_flat::, _>(bencher, vec![(0u32, 0u32); 1024]); } -#[bench] fn u8_u64_copy_flat_region(bencher: &mut Bencher) { _bench_copy_flat::, _>(bencher, vec![(0u8, 0u64); 512]); } -#[bench] fn str10_copy_flat_region(bencher: &mut Bencher) { _bench_copy_flat::, _>(bencher, vec!["grawwwwrr!"; 1024]); } -#[bench] fn str100_copy_flat_region(bencher: &mut Bencher) { _bench_copy_flat::, _>(bencher, vec!["grawwwwrrgrawwwwrrgrawwwwrrgrawwwwrrgrawwwwrrgrawwwwrrgrawwwwrrgrawwwwrrgrawwwwrr!!!!!!!!!grawwwwrr!"; 1024]); } -#[bench] fn string10_copy_flat_region(bencher: &mut Bencher) { _bench_copy_flat::, _>(bencher, vec![format!("grawwwwrr!"); 1024]); } -#[bench] fn string20_copy_flat_region(bencher: &mut Bencher) { _bench_copy_flat::, _>( bencher, vec![format!("grawwwwrr!!!!!!!!!!!"); 512], ); } -#[bench] fn vec_u_s_copy_flat_region(bencher: &mut Bencher) { _bench_copy_flat::, StringRegion>>>, _>( bencher, vec![vec![(0u64, "grawwwwrr!".to_string()); 32]; 32], ); } -#[bench] fn vec_u_vn_s_copy_flat_region(bencher: &mut Bencher) { _bench_copy_flat::< SliceRegion, OwnedRegion<_>, StringRegion>>>, @@ -362,7 +290,6 @@ fn vec_u_vn_s_copy_flat_region(bencher: &mut Bencher) { vec![vec![(0u64, vec![(); 1 << 40], "grawwwwrr!".to_string()); 32]; 32], ); } -#[bench] fn vec_u_vn_s_copy_flat_region_column(bencher: &mut Bencher) { _bench_copy_flat::< SliceRegion< @@ -511,3 +438,89 @@ where }); set_bytes(&mut bencher.bytes, siz); } + +benchmark_group!( + clone, + empty_clone, + str10_clone, + string10_clone, + string20_clone, + u32x2_clone, + u64_clone, + u8_u64_clone, + vec_u_s_clone, + vec_u_vn_s_clone, +); +benchmark_group!( + copy, + empty_copy, + str10_copy, + string10_copy, + string20_copy, + u32x2_copy, + u64_copy, + u8_u64_copy, + vec_u_s_copy, + vec_u_vn_s_copy, +); +benchmark_group!( + copy_flat, + empty_copy_flat, + str100_copy_flat, + str10_copy_flat, + string10_copy_flat, + string20_copy_flat, + u32x2_copy_flat, + u64_copy_flat, + u8_u64_copy_flat, + vec_u_s_copy_flat, + vec_u_vn_s_copy_flat, +); +benchmark_group!( + copy_region, + empty_copy_flat_region, + empty_copy_region, + str100_copy_flat_region, + str100_copy_region, + str10_copy_flat_region, + str10_copy_region, + string10_copy_flat_region, + string10_copy_region, + string10_copy_region_collapse, + string20_copy_flat_region, + string20_copy_region, + u32x2_copy_flat_region, + u32x2_copy_region, + u64_copy_flat_region, + u64_copy_region, + u8_u64_copy_flat_region, + u8_u64_copy_region, + vec_u_s_copy_flat_region, + vec_u_s_copy_region, + vec_u_vn_s_copy_flat_region, + vec_u_vn_s_copy_flat_region_column, + vec_u_vn_s_copy_region, + vec_u_vn_s_copy_region_column, +); +benchmark_group!( + alloc, + empty_prealloc, + empty_realloc, + str10_prealloc, + str10_realloc, + string10_prealloc, + string10_realloc, + string20_prealloc, + string20_realloc, + u32x2_prealloc, + u32x2_realloc, + u64_prealloc, + u64_realloc, + u8_u64_prealloc, + u8_u64_realloc, + vec_u_s_prealloc, + vec_u_s_realloc, + vec_u_vn_s_prealloc, + vec_u_vn_s_realloc, +); +benchmark_main!(clone, copy, copy_flat, copy_region, alloc);