aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAria Shrimpton <me@aria.rip>2024-03-10 18:37:40 +0000
committerAria Shrimpton <me@aria.rip>2024-03-10 18:37:40 +0000
commitb6fe87f7666a445bf7f55965b306e5a9d48bf42d (patch)
treeb0be8464db0e6b76252b97a81664f08ca57792a8
parent9a4cbc8c2690abfc1069bf6ab4f6584016358c00 (diff)
improve comparison output & nsplit alg
-rw-r--r--src/crates/candelabra/src/confirmation.rs8
-rw-r--r--src/crates/candelabra/src/cost/benchmark.rs16
-rw-r--r--src/crates/candelabra/src/profiler/info.rs9
-rw-r--r--src/crates/cli/src/select.rs29
4 files changed, 26 insertions, 36 deletions
diff --git a/src/crates/candelabra/src/confirmation.rs b/src/crates/candelabra/src/confirmation.rs
index 88bc190..3ec5b1b 100644
--- a/src/crates/candelabra/src/confirmation.rs
+++ b/src/crates/candelabra/src/confirmation.rs
@@ -62,9 +62,13 @@ impl State {
.context("Error running benchmark command")?;
let output = tee_output(child)?;
- Ok(parse_criterion_output(&output)
+ let mut map = parse_criterion_output(&output)
.map(|(name, result)| (name.to_string(), result))
- .collect())
+ .collect::<HashMap<_, _>>();
+
+ map.insert("total".to_string(), map.values().sum());
+
+ Ok(map)
}
/// Use the given selections for the container types in this project.
diff --git a/src/crates/candelabra/src/cost/benchmark.rs b/src/crates/candelabra/src/cost/benchmark.rs
index 812b023..5127442 100644
--- a/src/crates/candelabra/src/cost/benchmark.rs
+++ b/src/crates/candelabra/src/cost/benchmark.rs
@@ -76,7 +76,7 @@ pub fn run_benchmarks(name: &str, paths: &Paths, lib_specs: &LibSpecs) -> Result
let output = tee_output(child)?;
let measurements = parse_criterion_output(&output).flat_map(|(name, result)| {
let (op, n) = name.trim().split_once('/')?;
- Some((op, usize::from_str(n).ok()?, result))
+ Some((op.to_string(), usize::from_str(n).ok()?, result))
});
let mut by_op = HashMap::new();
@@ -115,14 +115,22 @@ pub(crate) fn tee_output(mut child: Child) -> Result<String> {
pub(crate) fn parse_criterion_output(
output: &str,
-) -> impl Iterator<Item = (&str, BenchmarkResult)> {
+) -> impl Iterator<Item = (String, BenchmarkResult)> + '_ {
output
.lines()
- .flat_map(|l| {
+ .enumerate()
+ .flat_map(|(i, l)| {
// looking for lines like:
// clear/100000 time: [1.3279 µs 1.4378 µs 1.5520 µs]
let mut spl = l.split("time:");
- Some((spl.next()?, spl.next()?))
+ let mut name = spl.next()?.trim().to_string();
+ if name.is_empty() {
+ // Sometimes criterion splits the name and time to different lines.
+ // We could deal with this better, but it makes the parsing code much more complicated for little benefit.
+ // Instead, fall back to the line number.
+ name = format!("l{i}");
+ }
+ Some((name, spl.next()?))
})
.flat_map(|(name, timings)| {
let mut timings = timings
diff --git a/src/crates/candelabra/src/profiler/info.rs b/src/crates/candelabra/src/profiler/info.rs
index 78ce299..30e7df7 100644
--- a/src/crates/candelabra/src/profiler/info.rs
+++ b/src/crates/candelabra/src/profiler/info.rs
@@ -109,9 +109,14 @@ impl UsageProfile {
let before = &top_by_partition[0].0;
let after = &top_by_partition[split_idx].0;
- let copy_n = self.0[split_idx].avg_n;
+ // halfway between the two partitions
+ let copy_n = {
+ let before = self.0[split_idx - 1].avg_n;
+ let after = self.0[split_idx].avg_n;
+ (before + after) / 2.0
+ };
let after_model = candidates.get(after).unwrap();
- let switching_cost = copy_n * after_model.by_op.get("insert")?.estimatef(copy_n / 2.0);
+ let switching_cost = copy_n * after_model.by_op.get("insert")?.estimatef(copy_n);
// see if it's "worth it"
let before_costs = &costs_by_partitions
diff --git a/src/crates/cli/src/select.rs b/src/crates/cli/src/select.rs
index 60285b8..cb4ed8b 100644
--- a/src/crates/cli/src/select.rs
+++ b/src/crates/cli/src/select.rs
@@ -70,34 +70,7 @@ impl State {
);
}
- let mut builder = Builder::default();
-
- if assignments_results.is_empty() {
- continue;
- }
-
- let header = {
- let mut header = vec!["assignment"];
- assignments_results
- .iter()
- .next()
- .unwrap()
- .1
- .keys()
- .for_each(|k| header.push(k));
- header
- };
- builder.set_header(header.clone());
-
- for (assignment, benchmark_results) in assignments_results.iter() {
- let mut record = vec![assignment.to_string()];
- for key in header.iter().skip(1) {
- record.push(format!("{:?}", benchmark_results.get(*key).unwrap()));
- }
- builder.push_record(record);
- }
-
- self.print_table_raw(builder.build());
+ self.print_table(assignments_results);
}
Ok(())
}