feat: add total timing

This commit is contained in:
Felix Spöttel 2021-12-29 19:14:40 +01:00
parent 7430afb606
commit 8441cb2fde
4 changed files with 123 additions and 26 deletions

View file

@ -81,10 +81,25 @@ cargo run --bin <day>
To run an optimized version for benchmarking, use the `--release` flag or the alias `cargo rr --bin <day>`. To run an optimized version for benchmarking, use the `--release` flag or the alias `cargo rr --bin <day>`.
### Run all solutions ### Run solutions for all days
```sh ```sh
cargo run cargo run
# output:
# Running `target/release/aoc`
# ----------
# | Day 01 |
# ----------
# 🎄 Part 1 🎄
#
# 0 (elapsed: 170.00µs)
#
# 🎄 Part 2 🎄
#
# 0 (elapsed: 30.00µs)
# <...other days...>
# Total: 0.20ms
``` ```
To run an optimized version for benchmarking, use the `--release` flag or the alias `cargo rr`. To run an optimized version for benchmarking, use the `--release` flag or the alias `cargo rr`.

View file

@ -19,8 +19,6 @@ module_path="src/bin/$filename.rs";
touch $module_path; touch $module_path;
cat > $module_path <<EOF cat > $module_path <<EOF
use aoc::{solve_day, read_file};
pub fn part_one(input: &str) -> u32 { pub fn part_one(input: &str) -> u32 {
0 0
} }
@ -30,7 +28,7 @@ pub fn part_two(input: &str) -> u32 {
} }
fn main() { fn main() {
solve_day!(&read_file("inputs", DAYNUM), part_one, part_two) aoc::solve!(&aoc::read_file("inputs", DAYNUM), part_one, part_two)
} }
#[cfg(test)] #[cfg(test)]

View file

@ -1,12 +1,12 @@
use std::env; use std::env;
use std::fs; use std::fs;
pub static ANSI_ITALIC: &str = "\x1b[3m"; pub const ANSI_ITALIC: &str = "\x1b[3m";
pub static ANSI_BOLD: &str = "\x1b[1m"; pub const ANSI_BOLD: &str = "\x1b[1m";
pub static ANSI_RESET: &str = "\x1b[0m"; pub const ANSI_RESET: &str = "\x1b[0m";
#[macro_export] #[macro_export]
macro_rules! solve_day { macro_rules! solve {
($input:expr, $part_one:ident, $part_two:ident) => {{ ($input:expr, $part_one:ident, $part_two:ident) => {{
use aoc::{ANSI_BOLD, ANSI_ITALIC, ANSI_RESET}; use aoc::{ANSI_BOLD, ANSI_ITALIC, ANSI_RESET};
use std::fmt::Display; use std::fmt::Display;
@ -40,3 +40,78 @@ pub fn read_file(folder: &str, day: u8) -> String {
let f = fs::read_to_string(filepath); let f = fs::read_to_string(filepath);
f.expect("could not open input file") f.expect("could not open input file")
} }
fn parse_time(val: &str, postfix: &str) -> f64 {
val.split(postfix).next().unwrap().parse().unwrap()
}
pub fn parse_exec_time(output: &str) -> f64 {
output.lines().fold(0_f64, |acc, l| {
if !l.contains("elapsed:") {
acc
} else {
let timing = l
.split("(elapsed: ")
.last()
.unwrap();
// see [rust/library/core/src/time.rs](https://git.io/Jy1rI)
if timing.ends_with("ns)") {
acc // range below rounding precision.
} else if timing.ends_with("µs)") {
acc + parse_time(timing, "µs") / 1000_f64
} else if timing.ends_with("ms)") {
acc + parse_time(timing, "ms")
} else if timing.ends_with("s)") {
acc + parse_time(timing, "s") * 1000_f64
} else {
acc
}
}
})
}
#[cfg(test)]
mod tests {
use super::*;
/// copied from: [rust/library/std/src/macros.rs](https://git.io/Jy1r7)
macro_rules! assert_approx_eq {
($a:expr, $b:expr) => {{
let (a, b) = (&$a, &$b);
assert!(
(*a - *b).abs() < 1.0e-6,
"{} is not approximately equal to {}",
*a,
*b
);
}};
}
#[test]
fn test_parse_exec_time() {
assert_approx_eq!(
parse_exec_time(
"🎄 Part 1 🎄\n0 (elapsed: 74.13ns)\n🎄 Part 2 🎄\n0 (elapsed: 50.00ns)"
),
0_f64
);
assert_approx_eq!(
parse_exec_time("🎄 Part 1 🎄\n0 (elapsed: 755µs)\n🎄 Part 2 🎄\n0 (elapsed: 700µs)"),
1.455_f64
);
assert_approx_eq!(
parse_exec_time("🎄 Part 1 🎄\n0 (elapsed: 70µs)\n🎄 Part 2 🎄\n0 (elapsed: 1.45ms)"),
1.52_f64
);
assert_approx_eq!(
parse_exec_time(
"🎄 Part 1 🎄\n0 (elapsed: 10.3s)\n🎄 Part 2 🎄\n0 (elapsed: 100.50ms)"
),
10400.50_f64
);
}
}

View file

@ -1,26 +1,35 @@
use aoc::{ANSI_BOLD, ANSI_RESET}; use aoc::{ANSI_BOLD, ANSI_ITALIC, ANSI_RESET};
use std::process::Command; use std::process::Command;
fn main() { fn main() {
(1..=25).for_each(|day| { let total: f64 = (1..=25)
let day = format!("{:02}", day); .map(|day| {
let day = format!("{:02}", day);
let cmd = Command::new("cargo") let cmd = Command::new("cargo")
.args(&["run", "--release", "--bin", &day]) .args(&["run", "--release", "--bin", &day])
.output() .output()
.unwrap(); .unwrap();
let output = String::from_utf8(cmd.stdout).unwrap(); println!("----------");
println!("----------"); println!("{}| Day {} |{}", ANSI_BOLD, day, ANSI_RESET);
println!("{}| Day {} |{}", ANSI_BOLD, day, ANSI_RESET); println!("----------");
println!("----------");
println!( let output = String::from_utf8(cmd.stdout).unwrap();
"{}", let is_empty = output.is_empty();
if !output.is_empty() {
output println!("{}", if is_empty { "Not solved." } else { &output });
if is_empty {
0_f64
} else { } else {
"Not solved.".to_string() aoc::parse_exec_time(&output)
} }
); })
}); .sum();
println!(
"{}Total:{} {}{:.2}ms{}",
ANSI_BOLD, ANSI_RESET, ANSI_ITALIC, total, ANSI_RESET
);
} }