Add a way to measure average execution time on multiple runs
authorGreg Burri <greg.burri@gmail.com>
Tue, 10 Dec 2024 16:36:33 +0000 (17:36 +0100)
committerGreg Burri <greg.burri@gmail.com>
Tue, 10 Dec 2024 16:36:33 +0000 (17:36 +0100)
src/main.rs

index 20fa7d8..98ac4b7 100644 (file)
@@ -37,11 +37,16 @@ mod utils;
 #[derive(Parser, Debug)]
 #[command(author = "Greg Burri", version = "1.0", about = "Advent of Code 2024")]
 struct Args {
-    #[arg(index(1), exclusive(true))]
+    #[arg(index(1), conflicts_with_all(["parallel"]))]
     day: Option<usize>,
 
+    /// Run all days in parallel.
     #[arg(short, long)]
     parallel: bool,
+
+    /// Number of time each day is executed, the average time is displayed.
+    #[arg(short, long, default_value_t = 1)]
+    repeat: u32,
 }
 
 fn main() {
@@ -79,7 +84,7 @@ fn main() {
     match args.day {
         Some(day) => {
             if day >= 1 && day <= days.len() {
-                do_day(&days, day)
+                do_day(&days, day, args.repeat)
             } else {
                 println!("Unknown day: {}", day)
             }
@@ -91,9 +96,9 @@ fn main() {
             if args.parallel {
                 (1..=days.len())
                     .into_par_iter()
-                    .for_each(|d| do_day(&days, d));
+                    .for_each(|d| do_day(&days, d, args.repeat));
             } else {
-                (1..=days.len()).for_each(|d| do_day(&days, d));
+                (1..=days.len()).for_each(|d| do_day(&days, d, args.repeat));
             }
 
             println!(
@@ -104,7 +109,7 @@ fn main() {
     }
 }
 
-fn do_day(days: &[fn(&mut dyn BufRead) -> String], day: usize) {
+fn do_day(days: &[fn(&mut dyn BufRead) -> String], day: usize, repeat: u32) {
     let filepath = format!("data/day{:02}.input", day);
     let mut f = fs::File::open(&filepath).unwrap_or_else(|error| {
         println!(
@@ -119,12 +124,17 @@ fn do_day(days: &[fn(&mut dyn BufRead) -> String], day: usize) {
     f.read_to_end(&mut buffer).unwrap();
 
     let now = Instant::now();
-    println!(
-        "Result of day {:02}: {} (time: {})",
-        day,
-        days[day - 1](&mut buffer.as_slice()),
-        format_micros(now.elapsed().as_micros())
-    );
+    for i in 0..repeat {
+        let result = days[day - 1](&mut buffer.as_slice());
+        if i == repeat - 1 {
+            println!(
+                "Result of day {:02}: {} (time: {})",
+                day,
+                result,
+                format_micros(now.elapsed().as_micros() / repeat as u128)
+            );
+        }
+    }
 }
 
 fn format_micros(t: u128) -> String {