From 2ae53bc4649b71a49dfd3fb8f7f8e5565a0c6c5d Mon Sep 17 00:00:00 2001 From: PlexSheep Date: Thu, 4 Apr 2024 21:07:52 +0200 Subject: [PATCH] more bench and report impls --- Cargo.toml | 2 ++ src/bench/builtin.rs | 8 ++++++-- src/bench/mod.rs | 9 ++++----- src/bench/report.rs | 32 ++++++++++++++++++++++++++++++-- 4 files changed, 42 insertions(+), 9 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index b9e47b2..7adea65 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,6 +24,7 @@ serde = ["dep:serde"] [dependencies] anyhow = "1.0.81" +chrono = { version = "0.4.37" } clap = { version = "4.5.3", features = ["derive"], optional = true } colored = { version = "2.1.0", optional = false } libpt = "0.4.2" @@ -31,6 +32,7 @@ rand = "0.8.5" regex = "1.10.3" serde = { version = "1.0.197", optional = true, features = ["serde_derive"] } serde_json = { version = "1.0.114", optional = true } +# serde_with = "3.7.0" thiserror = "1.0.58" [[bin]] diff --git a/src/bench/builtin.rs b/src/bench/builtin.rs index a343c69..7c8b313 100644 --- a/src/bench/builtin.rs +++ b/src/bench/builtin.rs @@ -11,8 +11,12 @@ pub struct BuiltinBenchmark<'wl, WL: WordList, SL: Solver<'wl, WL>> { builder: GameBuilder<'wl, WL>, } -impl<'wl, WL: WordList, SL: Solver<'wl, WL>> Benchmark<'wl, WL, SL> - for BuiltinBenchmark<'wl, WL, SL> +impl<'wl, WL, SL> Benchmark<'wl, WL, SL> for BuiltinBenchmark<'wl, WL, SL> +where + WL: WordList, + WL: 'wl, + SL: Solver<'wl, WL>, + SL: 'wl, { fn build(wordlist: &'wl WL, solver: SL) -> crate::error::WResult { let builder: GameBuilder<_> = Game::builder(wordlist); diff --git a/src/bench/mod.rs b/src/bench/mod.rs index a4bcf5d..d2b1cc3 100644 --- a/src/bench/mod.rs +++ b/src/bench/mod.rs @@ -19,6 +19,7 @@ where WL: WordList, WL: 'wl, SL: Solver<'wl, WL>, + SL: 'wl, { fn build(wordlist: &'wl WL, solver: SL) -> WResult; fn builder(&'wl self) -> &'wl GameBuilder<'wl, WL>; @@ -27,16 +28,12 @@ where } fn solver(&'wl self) -> &'wl SL; fn play(&'wl self) -> WResult { - // FIXME: wth why does the lifetime break here? - let mut game: Game<'wl, WL> = self.make_game()?; - - todo!() + self.solver().play(&mut self.make_game()?) } fn bench(&'wl self, n: usize) -> WResult { // PERF: it would be better to make this multithreaded let part = n / 20; let mut report = Report::new(); - let start = std::time::Instant::now(); for i in 0..n { // TODO: limit execution time for the following, perhaps async @@ -46,6 +43,8 @@ where } } + report.finalize(); + Ok(report) } } diff --git a/src/bench/report.rs b/src/bench/report.rs index fac9715..dbc3a20 100644 --- a/src/bench/report.rs +++ b/src/bench/report.rs @@ -1,3 +1,4 @@ +use chrono::{self, NaiveDateTime, NaiveTime, TimeDelta}; use std::fmt::Display; #[cfg(feature = "serde")] @@ -6,14 +7,24 @@ use serde::{Deserialize, Serialize}; use crate::game::response::GuessResponse; #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Report { data: Vec, + start: NaiveDateTime, + end: Option, + benchtime: Option, + /// is the benchmark finished? + finished: bool, } impl Report { pub fn new() -> Self { - Self { data: Vec::new() } + Self { + data: Vec::new(), + start: chrono::Local::now().naive_local(), + benchtime: None, + end: None, + finished: false, + } } pub fn add(&mut self, data: GuessResponse) { self.data.push(data) @@ -30,6 +41,23 @@ impl Report { pub fn avg_score(&self) -> usize { todo!() } + + /// finalize the record + /// + /// Sets the [benchtime](Report::benchtime) and [over](Report::over). In future versions, this + /// method might be used to precompute statistical information from the data. + pub(crate) fn finalize(&mut self) { + self.end = Some(chrono::Local::now().naive_local()); + self.benchtime = Some(self.end.unwrap() - self.start); + self.finished = true; + } + + /// is the report finished? + /// + /// Will be true after the [benchmark][super::Benchmark] is done. + pub fn finished(&self) -> bool { + self.finished + } } impl Display for Report {