Skip to content

Commit ead7a09

Browse files
committed
refactor: adapt walltime_results to runner
1 parent 3d18a8f commit ead7a09

4 files changed

Lines changed: 64 additions & 122 deletions

File tree

Cargo.lock

Lines changed: 20 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ debugid = "0.8.0"
5454
memmap2 = "0.9.5"
5555
nix = { version = "0.29.0", features = ["fs", "user"] }
5656
futures = "0.3.31"
57+
statrs = { version = "0.18.0", default-features = false }
5758

5859
[target.'cfg(target_os = "linux")'.dependencies]
5960
procfs = "0.17.0"
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,35 @@
1+
use crate::prelude::*;
2+
use std::path::Path;
3+
14
mod parser;
5+
mod walltime_results;
6+
7+
pub fn collect_walltime_results(stdout: &str, dst_dir: &Path) -> Result<()> {
8+
let benchmarks = parser::BenchmarkData::process_raw_results(parser::RawOutput::parse(stdout)?)
9+
.into_iter()
10+
.map(|result| {
11+
let uri = format!("{}::{}", result.package, result.name);
12+
walltime_results::WalltimeBenchmark::from_runtime_data(
13+
result.name,
14+
uri,
15+
result.times.into_iter().map(|t| t as u128).collect(),
16+
result.iters.into_iter().map(|i| i as u128).collect(),
17+
None,
18+
)
19+
})
20+
.collect::<Vec<_>>();
21+
debug!("Parsed {} benchmarks", benchmarks.len());
22+
23+
let pid = std::process::id();
24+
let creator = walltime_results::Creator {
25+
name: "runner".to_string(),
26+
version: env!("CARGO_PKG_VERSION").to_string(),
27+
pid,
28+
};
29+
let results = walltime_results::WalltimeResults::new(benchmarks, creator)?;
30+
31+
let mut file = std::fs::File::create(dst_dir.join(format!("{pid}.json")))?;
32+
serde_json::to_writer_pretty(&mut file, &results)?;
33+
34+
Ok(())
35+
}

src/run/runner/wall_time/golang/walltime_results.rs

Lines changed: 9 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
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

75
use serde::{Deserialize, Serialize};
86
use statrs::statistics::{Data, Distribution, Max, Min, OrderStatistics};
@@ -53,59 +51,6 @@ pub struct WalltimeBenchmark {
5351
}
5452

5553
impl 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

230157
impl 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

Comments
 (0)