From c124d392501919b5430e28cda08144fe6655607b Mon Sep 17 00:00:00 2001 From: Rico Hageman Date: Tue, 10 Dec 2024 21:42:04 +0000 Subject: [PATCH] Another attempt at codspeed --- .github/workflows/codspeed.yml | 40 +++++++++++++++++++++++++++++++++ .gitignore | 5 ++++- Cargo.toml | 12 +++++++++- benches/bench_days.rs | 41 ++++++++++++++++++++++++++++++++++ src/day1/mod.rs | 2 -- src/day10/mod.rs | 5 +---- src/day2/mod.rs | 5 +---- src/day3/mod.rs | 2 -- src/day4/mod.rs | 2 -- src/day5/mod.rs | 6 ----- src/day7/mod.rs | 3 --- src/day8/mod.rs | 2 -- src/day9/mod.rs | 13 ----------- src/lib.rs | 1 + 14 files changed, 99 insertions(+), 40 deletions(-) create mode 100644 .github/workflows/codspeed.yml create mode 100644 benches/bench_days.rs diff --git a/.github/workflows/codspeed.yml b/.github/workflows/codspeed.yml new file mode 100644 index 0000000..86b1b02 --- /dev/null +++ b/.github/workflows/codspeed.yml @@ -0,0 +1,40 @@ +name: CodSpeed + +on: + push: + branches: + - "main" + pull_request: + # `workflow_dispatch` allows CodSpeed to trigger backtest + # performance analysis in order to generate initial data. + workflow_dispatch: + +jobs: + benchmarks: + name: Run benchmarks + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Setup rust toolchain, cache and cargo-codspeed binary + uses: moonrepo/setup-rust@v1 + with: + cache-target: release + bins: cargo-codspeed, aoc-cli + + - name: Download available input files + env: + ADVENT_OF_CODE_SESSION: ${{ secrets.AOC_SESSION }} + run: | + mkdir -p inputs + for i in {1..25}; do + aoc download -I -i inputs/day$i.txt --year 2024 -d $i || true + done + - name: Build the benchmark target(s) + run: cargo codspeed build + + - name: Run the benchmarks + uses: CodSpeedHQ/action@v3 + with: + run: cargo codspeed run + token: ${{ secrets.CODSPEED_TOKEN }} \ No newline at end of file diff --git a/.gitignore b/.gitignore index d01bd1a..62487a5 100644 --- a/.gitignore +++ b/.gitignore @@ -18,4 +18,7 @@ Cargo.lock # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore # and can be added to the global gitignore or merged into this file. For a more nuclear # option (not recommended) you can uncomment the following to ignore the entire idea folder. -#.idea/ \ No newline at end of file +#.idea/ + +input/ + diff --git a/Cargo.toml b/Cargo.toml index 39b3083..c96b852 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,9 @@ edition = "2021" [lib] bench = false +[profile.release] +debug = true + [dependencies] aoc-runner = "0.3.0" aoc-runner-derive = "0.3.0" @@ -16,4 +19,11 @@ strum = "0.26.3" strum_macros = "0.26.4" [dev-dependencies] -criterion = { version = "2.7.2", package = "codspeed-criterion-compat" } +criterion = { version = "2.7.2", package = "codspeed-criterion-compat", default-features = false } +indoc = "2.0.5" +paste = "1.0.15" + + +[[bench]] +name = "bench_days" +harness = false diff --git a/benches/bench_days.rs b/benches/bench_days.rs new file mode 100644 index 0000000..12fcf2b --- /dev/null +++ b/benches/bench_days.rs @@ -0,0 +1,41 @@ +use criterion::{criterion_group, criterion_main, Criterion}; +use paste::paste; + +/// Get input for a single day +macro_rules! get_day_input { + ($day_num:literal) => { + include_str!(concat!("../inputs/day", $day_num, ".txt")) + }; +} + +/// Define benchmarks for a single day with part1 and part2 +macro_rules! benches_day { + ($day_num:literal) => { + paste! { + use advent_of_code_2024::[]; + + pub fn [](c: &mut Criterion) { + let mut group = c.benchmark_group(concat!("day", $day_num)); + let input = get_day_input!($day_num); + group.bench_function(format!("day{}_part1", $day_num), |b| b.iter(|| []::part1(input))); + group.bench_function(format!("day{}_part2", $day_num), |b| b.iter(|| []::part2(input))); + } + } + }; +} + +/// Create benchmarks for included days +macro_rules! benches { + ($($day_num:literal),*) => { + paste! { + $( + benches_day!($day_num); + )* + + criterion_group!(benches, $([]),*); + criterion_main!(benches); + } + }; +} + +benches!(1, 2, 3, 4, 5, 7, 8, 9, 10); \ No newline at end of file diff --git a/src/day1/mod.rs b/src/day1/mod.rs index 0106639..2b58f50 100644 --- a/src/day1/mod.rs +++ b/src/day1/mod.rs @@ -17,7 +17,6 @@ pub fn input_generator(input: &str) -> Input { .unzip() } -#[aoc(day1, part1)] pub fn part1(input: &str) -> Output { let (left, right) = input_generator(input); @@ -28,7 +27,6 @@ pub fn part1(input: &str) -> Output { .sum::() } -#[aoc(day1, part2)] pub fn part2(input: &str) -> Output { let (left, right) = input_generator(input); diff --git a/src/day10/mod.rs b/src/day10/mod.rs index 7f161b4..2fbefe4 100644 --- a/src/day10/mod.rs +++ b/src/day10/mod.rs @@ -1,7 +1,6 @@ use itertools::*; use rustc_hash::FxHashSet; use std::collections::VecDeque; -use std::fmt::Display; use strum::IntoEnumIterator; use strum_macros::EnumIter; @@ -114,7 +113,6 @@ impl Grid { } } -#[aoc(day10, part1)] pub fn part1(input: &str) -> usize { let grid = Grid::from_input(input); @@ -131,7 +129,6 @@ pub fn part1(input: &str) -> usize { .sum() } -#[aoc(day10, part2)] pub fn part2(input: &str) -> usize { let grid = Grid::from_input(input); @@ -139,7 +136,7 @@ pub fn part2(input: &str) -> usize { .map(|trail_head| { let mut rating = 0; - grid.find_trails_starting_at(trail_head, |trail_end| { + grid.find_trails_starting_at(trail_head, |_| { rating += 1; }); diff --git a/src/day2/mod.rs b/src/day2/mod.rs index 3044801..546c8ad 100644 --- a/src/day2/mod.rs +++ b/src/day2/mod.rs @@ -40,14 +40,12 @@ fn is_valid_report(report: &[u32]) -> bool { }) } -#[aoc(day2, part1)] pub fn part1(input: &str) -> Output { input_generator(input) .filter(|report| is_valid_report(report)) .count() } -#[aoc(day2, part2)] pub fn part2(input: &str) -> Output { let mut workhorse = Vec::with_capacity(5); @@ -61,14 +59,13 @@ pub fn part2(input: &str) -> Output { workhorse.extend_from_slice(report); let mut removed_element = workhorse.pop().unwrap(); - let mut temp = removed_element; if is_valid_report(&workhorse) { return true; } for index in (0..workhorse.len()).rev() { - temp = workhorse[index]; + let temp = workhorse[index]; workhorse[index] = removed_element; removed_element = temp; diff --git a/src/day3/mod.rs b/src/day3/mod.rs index 7108335..c60c5fd 100644 --- a/src/day3/mod.rs +++ b/src/day3/mod.rs @@ -14,7 +14,6 @@ fn parse_multiplication(input: &str) -> Output { left.parse::().unwrap() * right.parse::().unwrap() } -#[aoc(day3, part1)] pub fn part1(input: &str) -> Output { let regex = Regex::new(r"(mul\(\d*,\d*\))").unwrap(); regex @@ -23,7 +22,6 @@ pub fn part1(input: &str) -> Output { .sum() } -#[aoc(day3, part2)] pub fn part2(input: &str) -> Output { let regex = Regex::new(r"(mul\(\d*,\d*\))|(do\(\))|(don\'t\(\))").unwrap(); let (_, sum) = regex diff --git a/src/day4/mod.rs b/src/day4/mod.rs index 7d2885b..b9bbc88 100644 --- a/src/day4/mod.rs +++ b/src/day4/mod.rs @@ -116,7 +116,6 @@ impl Grid { } } -#[aoc(day4, part1)] pub fn part1(input: &str) -> Output { let grid = Grid::from_input(input); @@ -151,7 +150,6 @@ pub fn part1(input: &str) -> Output { .sum() } -#[aoc(day4, part2)] pub fn part2(input: &str) -> Output { let grid = Grid::from_input(input); diff --git a/src/day5/mod.rs b/src/day5/mod.rs index 492836d..8e8d526 100644 --- a/src/day5/mod.rs +++ b/src/day5/mod.rs @@ -1,5 +1,3 @@ -use itertools::Itertools; - type Element = u8; type Output = u16; @@ -24,14 +22,12 @@ impl BitSet { pub struct BitSetIterator { value: u128, - cur_index: u8, } impl BitSetIterator { pub fn new(value: u128) -> Self { Self { value, - cur_index: 0, } } } @@ -78,7 +74,6 @@ fn parse_input(input: &str) -> ([BitSet; 100], Vec>) { (rules, updates) } -#[aoc(day5, part1)] pub fn part1(input: &str) -> Output { let (rules, updates) = parse_input(input); @@ -113,7 +108,6 @@ pub fn part1(input: &str) -> Output { .sum() } -#[aoc(day5, part2)] pub fn part2(input: &str) -> Output { let (rules, mut updates) = parse_input(input); let mut index_of_element: [Option; 100] = [None; 100]; diff --git a/src/day7/mod.rs b/src/day7/mod.rs index 89be09a..dc65b30 100644 --- a/src/day7/mod.rs +++ b/src/day7/mod.rs @@ -1,4 +1,3 @@ -use itertools::Itertools; use std::collections::VecDeque; pub fn solve_with_operations(input: &str, allow_concatenation: bool) -> usize { @@ -52,12 +51,10 @@ pub fn solve_with_operations(input: &str, allow_concatenation: bool) -> usize { .sum() } -#[aoc(day7, part1)] pub fn part1(input: &str) -> usize { solve_with_operations(input, false) } -#[aoc(day7, part2)] pub fn part2(input: &str) -> usize { solve_with_operations(input, true) } diff --git a/src/day8/mod.rs b/src/day8/mod.rs index b9ed326..4a8b5c8 100644 --- a/src/day8/mod.rs +++ b/src/day8/mod.rs @@ -23,7 +23,6 @@ fn parse_input(input: &str) -> (isize, isize, HashMap> (width, height, antennas) } -#[aoc(day8, part1)] pub fn part1(input: &str) -> usize { let (width, height, antennas) = parse_input(input); @@ -53,7 +52,6 @@ pub fn part1(input: &str) -> usize { antinodes.len() } -#[aoc(day8, part2)] pub fn part2(input: &str) -> usize { let (width, height, antennas) = parse_input(input); diff --git a/src/day9/mod.rs b/src/day9/mod.rs index 3b8fe2d..7198e59 100644 --- a/src/day9/mod.rs +++ b/src/day9/mod.rs @@ -3,17 +3,6 @@ use std::cmp::Reverse; use std::collections::BinaryHeap; use std::fmt::{Display, Formatter}; -fn format_disk(disk: &[Option]) { - for element in disk { - let element = match element { - None => ".".to_string(), - Some(index) => index.to_string(), - }; - print!("{}", element); - } - println!(); -} - fn parse_input(input: &str) -> Disk { let mut disk = Disk::default(); let mut empty = false; @@ -33,7 +22,6 @@ fn parse_input(input: &str) -> Disk { disk } -#[aoc(day9, part1)] pub fn part1(input: &str) -> usize { let mut disk: Vec> = Vec::new(); let mut next_id = 0; @@ -159,7 +147,6 @@ impl Block { } } -#[aoc(day9, part2)] pub fn part2(input: &str) -> usize { let mut disk = parse_input(input); diff --git a/src/lib.rs b/src/lib.rs index 2f40dbf..893d10d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,6 +9,7 @@ pub mod day2; pub mod day3; pub mod day4; pub mod day5; +pub mod day7; pub mod day8; pub mod day9;