feat: add total
timing
This commit is contained in:
parent
7430afb606
commit
8441cb2fde
4 changed files with 123 additions and 26 deletions
17
README.md
17
README.md
|
@ -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>`.
|
||||
|
||||
### Run all solutions
|
||||
### Run solutions for all days
|
||||
|
||||
```sh
|
||||
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`.
|
||||
|
|
|
@ -19,8 +19,6 @@ module_path="src/bin/$filename.rs";
|
|||
touch $module_path;
|
||||
|
||||
cat > $module_path <<EOF
|
||||
use aoc::{solve_day, read_file};
|
||||
|
||||
pub fn part_one(input: &str) -> u32 {
|
||||
0
|
||||
}
|
||||
|
@ -30,7 +28,7 @@ pub fn part_two(input: &str) -> u32 {
|
|||
}
|
||||
|
||||
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)]
|
||||
|
|
83
src/lib.rs
83
src/lib.rs
|
@ -1,12 +1,12 @@
|
|||
use std::env;
|
||||
use std::fs;
|
||||
|
||||
pub static ANSI_ITALIC: &str = "\x1b[3m";
|
||||
pub static ANSI_BOLD: &str = "\x1b[1m";
|
||||
pub static ANSI_RESET: &str = "\x1b[0m";
|
||||
pub const ANSI_ITALIC: &str = "\x1b[3m";
|
||||
pub const ANSI_BOLD: &str = "\x1b[1m";
|
||||
pub const ANSI_RESET: &str = "\x1b[0m";
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! solve_day {
|
||||
macro_rules! solve {
|
||||
($input:expr, $part_one:ident, $part_two:ident) => {{
|
||||
use aoc::{ANSI_BOLD, ANSI_ITALIC, ANSI_RESET};
|
||||
use std::fmt::Display;
|
||||
|
@ -40,3 +40,78 @@ pub fn read_file(folder: &str, day: u8) -> String {
|
|||
let f = fs::read_to_string(filepath);
|
||||
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
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
45
src/main.rs
45
src/main.rs
|
@ -1,26 +1,35 @@
|
|||
use aoc::{ANSI_BOLD, ANSI_RESET};
|
||||
use aoc::{ANSI_BOLD, ANSI_ITALIC, ANSI_RESET};
|
||||
use std::process::Command;
|
||||
|
||||
fn main() {
|
||||
(1..=25).for_each(|day| {
|
||||
let day = format!("{:02}", day);
|
||||
let total: f64 = (1..=25)
|
||||
.map(|day| {
|
||||
let day = format!("{:02}", day);
|
||||
|
||||
let cmd = Command::new("cargo")
|
||||
.args(&["run", "--release", "--bin", &day])
|
||||
.output()
|
||||
.unwrap();
|
||||
let cmd = Command::new("cargo")
|
||||
.args(&["run", "--release", "--bin", &day])
|
||||
.output()
|
||||
.unwrap();
|
||||
|
||||
let output = String::from_utf8(cmd.stdout).unwrap();
|
||||
println!("----------");
|
||||
println!("{}| Day {} |{}", ANSI_BOLD, day, ANSI_RESET);
|
||||
println!("----------");
|
||||
println!(
|
||||
"{}",
|
||||
if !output.is_empty() {
|
||||
output
|
||||
println!("----------");
|
||||
println!("{}| Day {} |{}", ANSI_BOLD, day, ANSI_RESET);
|
||||
println!("----------");
|
||||
|
||||
let output = String::from_utf8(cmd.stdout).unwrap();
|
||||
let is_empty = output.is_empty();
|
||||
|
||||
println!("{}", if is_empty { "Not solved." } else { &output });
|
||||
|
||||
if is_empty {
|
||||
0_f64
|
||||
} else {
|
||||
"Not solved.".to_string()
|
||||
aoc::parse_exec_time(&output)
|
||||
}
|
||||
);
|
||||
});
|
||||
})
|
||||
.sum();
|
||||
|
||||
println!(
|
||||
"{}Total:{} {}{:.2}ms{}",
|
||||
ANSI_BOLD, ANSI_RESET, ANSI_ITALIC, total, ANSI_RESET
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue