1- use anyhow:: { Context , Result } ;
2- use std:: {
3- io:: Write ,
4- path:: { Path , PathBuf } ,
5- } ;
1+ // NOTE: This file was taken from `codspeed-rust` and modified a bit to fit this project.
2+
3+ use anyhow:: Result ;
64
75use serde:: { Deserialize , Serialize } ;
86use statrs:: statistics:: { Data , Distribution , Max , Min , OrderStatistics } ;
@@ -53,59 +51,6 @@ pub struct WalltimeBenchmark {
5351}
5452
5553impl WalltimeBenchmark {
56- /// Entry point called in patched integration to harvest raw walltime data
57- ///
58- /// `CODSPEED_CARGO_WORKSPACE_ROOT` is expected to be set for this to work
59- ///
60- /// # Arguments
61- ///
62- /// - `scope`: The used integration, e.g. "divan" or "criterion"
63- /// - `name`: The name of the benchmark
64- /// - `uri`: The URI of the benchmark
65- /// - `iters_per_round`: The number of iterations for each round (=sample_size), e.g. `[1, 2, 3]` (variable) or `[2, 2, 2, 2]` (constant).
66- /// - `times_per_round_ns`: The measured time for each round in nanoseconds, e.g. `[1000, 2000, 3000]`
67- /// - `max_time_ns`: The time limit for the benchmark in nanoseconds (if defined)
68- ///
69- /// # Pseudo-code
70- ///
71- /// ```text
72- /// let sample_count = /* The number of executions for the same benchmark. */
73- /// let sample_size = iters_per_round = vec![/* The number of iterations within each sample. */];
74- /// for round in 0..sample_count {
75- /// let times_per_round_ns = 0;
76- /// for iteration in 0..sample_size[round] {
77- /// run_benchmark();
78- /// times_per_round_ns += /* measured execution time */;
79- /// }
80- /// }
81- /// ```
82- ///
83- pub fn collect_raw_walltime_results (
84- scope : & str ,
85- name : String ,
86- uri : String ,
87- iters_per_round : Vec < u128 > ,
88- times_per_round_ns : Vec < u128 > ,
89- max_time_ns : Option < u128 > ,
90- ) {
91- if !crate :: utils:: running_with_codspeed_runner ( ) {
92- return ;
93- }
94- let workspace_root = std:: env:: var ( "CODSPEED_CARGO_WORKSPACE_ROOT" ) . map ( PathBuf :: from) ;
95- let Ok ( workspace_root) = workspace_root else {
96- eprintln ! ( "codspeed failed to get workspace root. skipping" ) ;
97- return ;
98- } ;
99- let data = WalltimeBenchmark :: from_runtime_data (
100- name,
101- uri,
102- iters_per_round,
103- times_per_round_ns,
104- max_time_ns,
105- ) ;
106- data. dump_to_results ( & workspace_root, scope) ;
107- }
108-
10954 pub fn from_runtime_data (
11055 name : String ,
11156 uri : String ,
@@ -187,24 +132,6 @@ impl WalltimeBenchmark {
187132 stats,
188133 }
189134 }
190-
191- fn dump_to_results ( & self , workspace_root : & Path , scope : & str ) {
192- let output_dir = result_dir_from_workspace_root ( workspace_root) . join ( scope) ;
193- std:: fs:: create_dir_all ( & output_dir) . unwrap ( ) ;
194- let bench_id = uuid:: Uuid :: new_v4 ( ) . to_string ( ) ;
195- let output_path = output_dir. join ( format ! ( "{bench_id}.json" ) ) ;
196- let mut writer = std:: fs:: File :: create ( & output_path) . expect ( "Failed to create the file" ) ;
197- serde_json:: to_writer_pretty ( & mut writer, self ) . expect ( "Failed to write the data" ) ;
198- writer. flush ( ) . expect ( "Failed to flush the writer" ) ;
199- }
200-
201- pub fn is_invalid ( & self ) -> bool {
202- self . stats . min_ns < f64:: EPSILON
203- }
204-
205- pub fn name ( & self ) -> & str {
206- & self . metadata . name
207- }
208135}
209136
210137#[ derive( Debug , Serialize , Deserialize ) ]
@@ -214,10 +141,10 @@ struct Instrument {
214141}
215142
216143#[ derive( Debug , Serialize , Deserialize ) ]
217- struct Creator {
218- name : String ,
219- version : String ,
220- pid : u32 ,
144+ pub struct Creator {
145+ pub name : String ,
146+ pub version : String ,
147+ pub pid : u32 ,
221148}
222149
223150#[ derive( Debug , Serialize , Deserialize ) ]
@@ -228,55 +155,15 @@ pub struct WalltimeResults {
228155}
229156
230157impl WalltimeResults {
231- pub fn collect_walltime_results ( workspace_root : & Path ) -> Result < Self > {
232- // retrieve data from `{workspace_root}/target/codspeed/raw_results/{scope}/*.json
233- let benchmarks = glob:: glob ( & format ! (
234- "{}/**/*.json" ,
235- result_dir_from_workspace_root( workspace_root)
236- . to_str( )
237- . unwrap( ) ,
238- ) ) ?
239- . map ( |sample| -> Result < _ > {
240- let sample = sample?;
241- serde_json:: from_reader :: < _ , WalltimeBenchmark > ( std:: fs:: File :: open ( & sample) ?)
242- . context ( "Failed to read benchmark data" )
243- } )
244- . collect :: < Result < Vec < _ > > > ( ) ?;
245-
158+ pub fn new ( benchmarks : Vec < WalltimeBenchmark > , creator : Creator ) -> Result < Self > {
246159 Ok ( WalltimeResults {
247160 instrument : Instrument {
248161 type_ : "walltime" . to_string ( ) ,
249162 } ,
250- creator : Creator {
251- name : "codspeed-rust" . to_string ( ) ,
252- version : env ! ( "CARGO_PKG_VERSION" ) . to_string ( ) ,
253- pid : std:: process:: id ( ) ,
254- } ,
163+ creator,
255164 benchmarks,
256165 } )
257166 }
258-
259- pub fn clear ( workspace_root : & Path ) -> Result < ( ) > {
260- let raw_results_dir = result_dir_from_workspace_root ( workspace_root) ;
261- std:: fs:: remove_dir_all ( & raw_results_dir) . ok ( ) ; // ignore errors when the directory does not exist
262- std:: fs:: create_dir_all ( & raw_results_dir)
263- . context ( "Failed to create raw_results directory" ) ?;
264- Ok ( ( ) )
265- }
266-
267- pub fn benchmarks ( & self ) -> & [ WalltimeBenchmark ] {
268- & self . benchmarks
269- }
270- }
271-
272- // FIXME: This assumes that the cargo target dir is `target`, and duplicates information with
273- // `cargo-codspeed::helpers::get_codspeed_target_dir`
274- fn result_dir_from_workspace_root ( workspace_root : & Path ) -> PathBuf {
275- workspace_root
276- . join ( "target" )
277- . join ( "codspeed" )
278- . join ( "walltime" )
279- . join ( "raw_results" )
280167}
281168
282169#[ cfg( test) ]
0 commit comments