generated from PlexSheep/rs-base
bench with multithreading
cargo devel CI / cargo CI (push) Successful in 1m46s
Details
cargo devel CI / cargo CI (push) Successful in 1m46s
Details
This commit is contained in:
parent
966f73efef
commit
88d388807f
|
@ -29,6 +29,7 @@ clap = { version = "4.5.3", features = ["derive"], optional = true }
|
||||||
colored = { version = "2.1.0", optional = false }
|
colored = { version = "2.1.0", optional = false }
|
||||||
libpt = "0.4.2"
|
libpt = "0.4.2"
|
||||||
rand = "0.8.5"
|
rand = "0.8.5"
|
||||||
|
rayon = "1.10.0"
|
||||||
regex = "1.10.3"
|
regex = "1.10.3"
|
||||||
serde = { version = "1.0.197", optional = true, features = ["serde_derive"] }
|
serde = { version = "1.0.197", optional = true, features = ["serde_derive"] }
|
||||||
serde_json = { version = "1.0.114", optional = true }
|
serde_json = { version = "1.0.114", optional = true }
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
use std::fmt::{Debug, Display};
|
use std::fmt::Debug;
|
||||||
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
use libpt::log::debug;
|
use libpt::log::debug;
|
||||||
|
use rayon::prelude::*;
|
||||||
|
|
||||||
use crate::error::WResult;
|
use crate::error::WResult;
|
||||||
use crate::game::response::GuessResponse;
|
use crate::game::response::GuessResponse;
|
||||||
|
@ -17,7 +19,7 @@ pub mod builtin;
|
||||||
/// Default amount of games to play for a [Benchmark]
|
/// Default amount of games to play for a [Benchmark]
|
||||||
pub const DEFAULT_N: usize = 50;
|
pub const DEFAULT_N: usize = 50;
|
||||||
|
|
||||||
pub trait Benchmark<'wl, WL, SL>: Clone + Sized + Debug
|
pub trait Benchmark<'wl, WL, SL>: Clone + Sized + Debug + Sync
|
||||||
where
|
where
|
||||||
WL: WordList,
|
WL: WordList,
|
||||||
WL: 'wl,
|
WL: 'wl,
|
||||||
|
@ -40,21 +42,26 @@ where
|
||||||
// TODO: add some interface to get reports while the benchmark runs
|
// TODO: add some interface to get reports while the benchmark runs
|
||||||
// TODO: make the benchmark optionally multithreaded
|
// TODO: make the benchmark optionally multithreaded
|
||||||
fn bench(&'wl self, n: usize) -> WResult<Report> {
|
fn bench(&'wl self, n: usize) -> WResult<Report> {
|
||||||
// PERF: it would be better to make this multithreaded
|
|
||||||
let part = match n / 20 {
|
let part = match n / 20 {
|
||||||
0 => 19,
|
0 => 19,
|
||||||
other => other,
|
other => other,
|
||||||
};
|
};
|
||||||
let mut report = Report::new();
|
let report = Arc::new(Mutex::new(Report::new()));
|
||||||
|
let this = std::sync::Arc::new(self);
|
||||||
|
|
||||||
for i in 0..n {
|
(0..n)
|
||||||
report.add(self.play()?);
|
.into_par_iter()
|
||||||
if i % part == part - 1 {
|
.for_each_with(report.clone(), |outside_data, _i| {
|
||||||
// TODO: add the report to the struct so that users can poll it to print the status
|
let report = outside_data;
|
||||||
// TODO: update the report in the struct
|
let r = this
|
||||||
}
|
.play()
|
||||||
}
|
.expect("error playing the game during benchmark");
|
||||||
|
report.lock().expect("lock is poisoned").add(r);
|
||||||
|
});
|
||||||
|
|
||||||
|
// FIXME: find some way to take the Report from the Mutex
|
||||||
|
// Mutex::into_inner() does not work
|
||||||
|
let mut report: Report = report.lock().unwrap().clone();
|
||||||
report.finalize();
|
report.finalize();
|
||||||
|
|
||||||
Ok(report)
|
Ok(report)
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
|
use crate::bench::report::Report;
|
||||||
use crate::wlist::word::Word;
|
use crate::wlist::word::Word;
|
||||||
|
|
||||||
pub type WResult<T> = std::result::Result<T, Error>;
|
pub type WResult<T> = std::result::Result<T, Error>;
|
||||||
|
@ -25,6 +26,11 @@ pub enum Error {
|
||||||
#[from]
|
#[from]
|
||||||
source: regex::Error,
|
source: regex::Error,
|
||||||
},
|
},
|
||||||
|
#[error("Error sharing the benchmark data over multiple threads")]
|
||||||
|
Mutex {
|
||||||
|
#[from]
|
||||||
|
source: std::sync::PoisonError<Report>
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Error)]
|
#[derive(Debug, Clone, Error)]
|
||||||
|
|
|
@ -37,7 +37,7 @@ pub use stupid::StupidSolver;
|
||||||
///
|
///
|
||||||
/// If you want to have the user select a model, create an enum with it's variants containing your
|
/// If you want to have the user select a model, create an enum with it's variants containing your
|
||||||
/// [Solvers][Solver] and have this enum implement [Solver], see [AnyBuiltinSolver].
|
/// [Solvers][Solver] and have this enum implement [Solver], see [AnyBuiltinSolver].
|
||||||
pub trait Solver<'wl, WL: WordList>: Clone + std::fmt::Debug + Sized {
|
pub trait Solver<'wl, WL: WordList>: Clone + std::fmt::Debug + Sized + Sync {
|
||||||
/// Build and initialize a [Solver]
|
/// Build and initialize a [Solver]
|
||||||
fn build(wordlist: &'wl WL) -> WResult<Self>;
|
fn build(wordlist: &'wl WL) -> WResult<Self>;
|
||||||
/// Calculate the next guess for a [Game]
|
/// Calculate the next guess for a [Game]
|
||||||
|
|
|
@ -15,7 +15,7 @@ use crate::error::WResult;
|
||||||
|
|
||||||
pub type AnyWordlist = Box<dyn WordList>;
|
pub type AnyWordlist = Box<dyn WordList>;
|
||||||
|
|
||||||
pub trait WordList: Clone + std::fmt::Debug + Default {
|
pub trait WordList: Clone + std::fmt::Debug + Default + Sync {
|
||||||
fn solutions(&self) -> ManyWordDatas {
|
fn solutions(&self) -> ManyWordDatas {
|
||||||
let wmap = self.wordmap().clone();
|
let wmap = self.wordmap().clone();
|
||||||
let threshold = wmap.threshold();
|
let threshold = wmap.threshold();
|
||||||
|
|
Loading…
Reference in New Issue