aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAria Shrimpton <me@aria.rip>2024-01-31 21:34:15 +0000
committerAria Shrimpton <me@aria.rip>2024-01-31 21:34:15 +0000
commitdb30ce4e436641513568d5e5ae37f7100594156c (patch)
tree1b6ee3b8e2b32d6ef83c05c2f7b498744d52a22b
parent6c8407043120f3855dd0229c0f838041c7f0eb38 (diff)
breakdown cost by split in estimate command
-rw-r--r--src/crates/candelabra/src/profiler/info.rs7
-rw-r--r--src/crates/cli/src/estimate.rs40
2 files changed, 44 insertions, 3 deletions
diff --git a/src/crates/candelabra/src/profiler/info.rs b/src/crates/candelabra/src/profiler/info.rs
index dc9a03c..398f4e0 100644
--- a/src/crates/candelabra/src/profiler/info.rs
+++ b/src/crates/candelabra/src/profiler/info.rs
@@ -80,6 +80,13 @@ impl ProfilerPartition {
estimator.estimatef(self.avg_n) * self.avg_op_count(op) * self.occurences
}
+ /// Get a breakdown of the cost by operation
+ pub fn cost_breakdown<'a>(&'a self, cost_model: &'a CostModel) -> CostBreakdown<'a> {
+ self.avg_op_counts
+ .keys()
+ .flat_map(|op| Some((op, self.op_cost(op, cost_model.by_op.get(op)?))))
+ .collect()
+ }
fn add_lifetime(&mut self, (n, ops): (f64, HashMap<String, usize>)) {
self.avg_n = self.avg_n + (n - self.avg_n) / (self.occurences + 1.0);
for (op, count) in ops {
diff --git a/src/crates/cli/src/estimate.rs b/src/crates/cli/src/estimate.rs
index 6f4716f..eafe101 100644
--- a/src/crates/cli/src/estimate.rs
+++ b/src/crates/cli/src/estimate.rs
@@ -40,15 +40,30 @@ impl State {
info!("Using assignments: {:?}", &assignments);
// get breakdown by operation for each assignment
- info!("Contribution to cost by operation:");
+ info!("Summary breakdown:");
let profile_info = self.inner.profiler_info(proj)?;
+ let cost_models = profile_info
+ .keys()
+ .map(|ctn| {
+ (
+ ctn,
+ assignments
+ .get(ctn)
+ .ok_or_else(|| anyhow!("missing assignment for {}", ctn)),
+ )
+ })
+ .map(|(ctn, impl_name)| Ok((ctn, self.inner.cost_model(impl_name?)?)))
+ .collect::<Result<HashMap<_, _>>>()?;
+
let mut acc = HashMap::new();
- for (con_type_name, impl_name) in assignments.iter() {
+ for con_type_name in assignments.keys() {
let profiler = profile_info
.get(*con_type_name)
.ok_or_else(|| anyhow!("no profiling info for {} - wrong name?", con_type_name))?;
- let cost_model = self.inner.cost_model(impl_name)?;
+
+ let cost_model = cost_models.get(con_type_name).unwrap();
+
let breakdown = profiler.cost_breakdown(&cost_model);
acc.insert(
*con_type_name,
@@ -61,10 +76,29 @@ impl State {
print_table(acc);
+ info!("Breakdown by split");
+ profile_info
+ .iter()
+ .map(|(ctn, p)| (ctn, cost_models.get(ctn).unwrap(), p))
+ .map(|(ctn, cost_model, p)| {
+ (
+ ctn,
+ p.0.iter().enumerate().map(|(i, partition)| {
+ (i, partition.cost_breakdown(cost_model).into_iter())
+ }),
+ )
+ })
+ .for_each(|(ctn, table)| {
+ info!("{}:", ctn);
+ print_table(table);
+ });
+
if !args.run {
return Ok(());
}
+ info!("Running benchmarks for comparison");
+
print_table(
self.inner
.run_benchmarks_with(proj, &assignments)?