diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e36a69a1..6cf6cbfb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,6 +10,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 + with: + submodules: true - uses: moonrepo/setup-rust@v1 with: components: rustfmt, clippy @@ -21,6 +23,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 + with: + submodules: true - uses: moonrepo/setup-rust@v1 with: bins: cargo-msrv @@ -35,6 +39,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 + with: + submodules: true - uses: moonrepo/setup-rust@v1 - run: cargo test --all @@ -42,6 +48,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 + with: + submodules: true - uses: moonrepo/setup-rust@v1 with: cache-target: release @@ -65,6 +73,8 @@ jobs: runs-on: codspeed-macro steps: - uses: actions/checkout@v4 + with: + submodules: true - uses: moonrepo/setup-rust@v1 with: cache-target: release diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 97e917bb..a5d77d39 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -14,6 +14,7 @@ jobs: steps: - uses: actions/checkout@v4 with: + submodules: true fetch-depth: 0 - uses: moonrepo/setup-rust@v0 with: diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..28c853ff --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ + +[submodule "crates/divan_compat/examples/src/the_algorithms/Rust"] + path = crates/divan_compat/examples/src/the_algorithms/Rust + url = git@github.com:TheAlgorithms/Rust.git diff --git a/Cargo.lock b/Cargo.lock index f4848ce6..efa8ebeb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -627,6 +627,8 @@ version = "0.0.0" dependencies = [ "codspeed-divan-compat", "fastrand 2.3.0", + "num-bigint", + "num-traits", ] [[package]] diff --git a/crates/divan_compat/examples/Cargo.toml b/crates/divan_compat/examples/Cargo.toml index 39931093..67de38e0 100644 --- a/crates/divan_compat/examples/Cargo.toml +++ b/crates/divan_compat/examples/Cargo.toml @@ -6,9 +6,16 @@ description = "Examples for Divan, a comfy benchmarking framework." publish = false license = "MIT OR Apache-2.0" + [dependencies] -fastrand = "2.3.0" divan = { package = "codspeed-divan-compat", path = ".." } +fastrand = "2.3.0" +num-bigint = { version = "0.4", optional = true } +num-traits = { version = "0.2", optional = true } + +[features] +default = ["big-math"] +big-math = ["num-bigint", "num-traits"] [[bench]] name = "math" @@ -21,3 +28,7 @@ harness = false [[bench]] name = "time" harness = false + +[[bench]] +name = "the_algorithms" +harness = false diff --git a/crates/divan_compat/examples/benches/the_algorithms.rs b/crates/divan_compat/examples/benches/the_algorithms.rs new file mode 100644 index 00000000..b996f41c --- /dev/null +++ b/crates/divan_compat/examples/benches/the_algorithms.rs @@ -0,0 +1,188 @@ +use codspeed_divan_compat_examples::the_algorithms; +use divan::black_box; + +fn main() { + divan::main(); +} + +mod backtracking { + use super::*; + + #[divan::bench(args = [4, 5, 6, 7, 8])] + fn n_queens_solver(n: usize) -> Vec> { + the_algorithms::backtracking::n_queens_solver(n) + } + + // Benchmark parentheses generation with different sizes + #[divan::bench(args = [3, 4, 5, 6])] + fn generate_parentheses(n: usize) -> Vec { + the_algorithms::backtracking::generate_parentheses(n) + } + + // Benchmark combinations generation with different n values, keeping k=3 + #[divan::bench(args = [5, 6, 7, 8, 9])] + fn generate_combinations(n: usize) -> Vec> { + the_algorithms::backtracking::generate_all_combinations(n, 3).unwrap() + } + + // Benchmark graph coloring with different sizes of complete graphs + #[divan::bench(args = [3, 4, 5, 6])] + fn graph_coloring(bencher: divan::Bencher, n: usize) { + // Create a complete graph of size n (all vertices connected to each other) + let matrix = (0..n) + .map(|i| (0..n).map(|j| i != j).collect()) + .collect::>>(); + + bencher.bench_local(|| { + black_box(the_algorithms::backtracking::generate_colorings( + black_box(matrix.clone()), + 3, + )) + }); + } + + // Benchmark Hamiltonian cycle finding with different sizes of cyclic graphs + #[divan::bench(args = [4, 5, 6, 7])] + fn hamiltonian_cycle(bencher: divan::Bencher, n: usize) { + // Create a cyclic graph where each vertex is connected to its neighbors + // This ensures a Hamiltonian cycle exists + let matrix = (0..n) + .map(|i| { + (0..n) + .map(|j| { + let prev = (i + n - 1) % n; + let next = (i + 1) % n; + j == prev || j == next + }) + .collect() + }) + .collect::>>(); + + bencher.bench_local(|| { + black_box(the_algorithms::backtracking::find_hamiltonian_cycle( + black_box(matrix.clone()), + 0, + )) + }); + } + + // Benchmark Knight's Tour with different board sizes + #[divan::bench(args = [5, 6, 7, 8])] + fn knight_tour(bencher: divan::Bencher, n: usize) { + bencher.bench_local(|| { + black_box(the_algorithms::backtracking::find_knight_tour( + black_box(n), + black_box(n), + black_box(0), + black_box(0), + )) + }); + } + + // Benchmark permutations with different input sizes + #[divan::bench(args = [3, 4, 5, 6, 7])] + fn permutations(bencher: divan::Bencher, n: usize) { + let nums: Vec = (0..n).map(|x| x as isize).collect(); + + bencher.bench_local(|| { + black_box(the_algorithms::backtracking::permute(black_box( + nums.clone(), + ))) + }); + } + + // Benchmark Rat in Maze with different maze sizes + #[divan::bench(args = [5, 6, 7, 8])] + fn rat_in_maze(bencher: divan::Bencher, n: usize) { + // Create a maze where the rat can move diagonally to the end + let maze = (0..n) + .map(|i| (0..n).map(|j| i == j || i == j + 1).collect()) + .collect::>>(); + + bencher.bench_local(|| { + black_box(the_algorithms::backtracking::find_path_in_maze( + black_box(&maze), + black_box(0), + black_box(0), + )) + }); + } + + // Benchmark Subset Sum with different set sizes + #[divan::bench(args = [10, 12, 14, 16, 18])] + fn subset_sum(bencher: divan::Bencher, n: usize) { + let set: Vec = (0..n).map(|x| x as isize).collect(); + let target = (n as isize) * 2; // A challenging but achievable target + + bencher.bench_local(|| { + black_box(the_algorithms::backtracking::has_subset_with_sum( + black_box(&set), + black_box(target), + )) + }); + } + + // Benchmark Sudoku solver with different levels of difficulty + #[divan::bench] + fn sudoku(bencher: divan::Bencher) { + // A moderately difficult Sudoku puzzle + let board = [ + [3, 0, 6, 5, 0, 8, 4, 0, 0], + [5, 2, 0, 0, 0, 0, 0, 0, 0], + [0, 8, 7, 0, 0, 0, 0, 3, 1], + [0, 0, 3, 0, 1, 0, 0, 8, 0], + [9, 0, 0, 8, 6, 3, 0, 0, 5], + [0, 5, 0, 0, 9, 0, 6, 0, 0], + [1, 3, 0, 0, 0, 0, 2, 5, 0], + [0, 0, 0, 0, 0, 0, 0, 7, 4], + [0, 0, 5, 2, 0, 6, 3, 0, 0], + ]; + + bencher.bench_local(|| { + black_box(the_algorithms::backtracking::sudoku_solver(black_box( + &board, + ))) + }); + } +} + +mod bit_manipulation { + use super::*; + + #[divan::bench(args = [0, 42, 255, 1024, 65535])] + fn count_set_bits(bencher: divan::Bencher, n: u32) { + bencher.bench_local(|| { + black_box(the_algorithms::bit_manipulation::count_set_bits(black_box( + n.try_into().unwrap(), + ))) + }); + } + + #[divan::bench(args = [0, 42, 255, 1024, 65535])] + fn find_highest_set_bit(bencher: divan::Bencher, n: u32) { + bencher.bench_local(|| { + black_box(the_algorithms::bit_manipulation::find_highest_set_bit( + black_box(n.try_into().unwrap()), + )) + }); + } + + #[divan::bench(args = [1, 2, 3, 4, 5])] + fn generate_gray_code(bencher: divan::Bencher, n: u32) { + bencher.bench_local(|| { + black_box(the_algorithms::bit_manipulation::generate_gray_code( + black_box(n.try_into().unwrap()), + )) + }); + } + + #[divan::bench(args = &[(0, 0), (42, 13), (255, 255), (1024, -1024), (65535, -65535)])] + fn add_two_integers(bencher: divan::Bencher, (a, b): (i32, i32)) { + bencher.bench_local(|| { + black_box(the_algorithms::bit_manipulation::add_two_integers( + black_box(a.try_into().unwrap()), + black_box(b.try_into().unwrap()), + )) + }); + } +} diff --git a/crates/divan_compat/examples/src/lib.rs b/crates/divan_compat/examples/src/lib.rs new file mode 100644 index 00000000..fccc83d6 --- /dev/null +++ b/crates/divan_compat/examples/src/lib.rs @@ -0,0 +1,2 @@ +#[allow(clippy::all)] +pub mod the_algorithms; diff --git a/crates/divan_compat/examples/src/the_algorithms/Rust b/crates/divan_compat/examples/src/the_algorithms/Rust new file mode 160000 index 00000000..ae10da6a --- /dev/null +++ b/crates/divan_compat/examples/src/the_algorithms/Rust @@ -0,0 +1 @@ +Subproject commit ae10da6afebe2c138db410b9edd8607c9ac706f0 diff --git a/crates/divan_compat/examples/src/the_algorithms/mod.rs b/crates/divan_compat/examples/src/the_algorithms/mod.rs new file mode 100644 index 00000000..c5ddc5ec --- /dev/null +++ b/crates/divan_compat/examples/src/the_algorithms/mod.rs @@ -0,0 +1,5 @@ +#[path = "./Rust/src/bit_manipulation/mod.rs"] +pub mod bit_manipulation; + +#[path = "./Rust/src/backtracking/mod.rs"] +pub mod backtracking;