Skip to content

Commit 72fcfc0

Browse files
committed
create bench_local_diff command
1 parent 533f2dd commit 72fcfc0

File tree

3 files changed

+126
-3
lines changed

3 files changed

+126
-3
lines changed

Cargo.lock

+11-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

collector/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ regex = "1.7.1"
4444
analyzeme = "12.0.0"
4545

4646
benchlib = { path = "benchlib" }
47+
itertools = "0.13.0"
4748

4849
[target.'cfg(windows)'.dependencies]
4950
miow = "0.3"

collector/src/bin/collector.rs

+114-2
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,12 @@ use anyhow::Context;
1919
use clap::builder::TypedValueParser;
2020
use clap::{Arg, Parser};
2121
use humansize::{format_size, BINARY};
22+
use itertools::Itertools;
2223
use rayon::iter::{IndexedParallelIterator, IntoParallelRefIterator, ParallelIterator};
2324
use tabled::builder::Builder;
2425
use tabled::settings::object::{Columns, Rows};
2526
use tabled::settings::{Alignment, Border, Color, Modify};
27+
use tabled::{Table, Tabled};
2628
use tokio::runtime::Runtime;
2729

2830
use collector::api::next_artifact::NextArtifact;
@@ -52,7 +54,7 @@ use collector::toolchain::{
5254
use collector::utils::cachegrind::cachegrind_diff;
5355
use collector::utils::{is_installed, wait_for_future};
5456
use collector::{utils, CollectorCtx, CollectorStepBuilder};
55-
use database::{ArtifactId, ArtifactIdNumber, Commit, CommitType, Connection, Pool};
57+
use database::{ArtifactId, ArtifactIdNumber, Commit, CommitType, Connection, Lookup, Pool};
5658

5759
fn n_normal_benchmarks_remaining(n: usize) -> String {
5860
let suffix = if n == 1 { "" } else { "s" };
@@ -628,6 +630,18 @@ enum Commands {
628630
#[command(flatten)]
629631
db: DbOption,
630632
},
633+
634+
/// Displays diff between two local bench result.
635+
BenchLocalDiff {
636+
#[command(flatten)]
637+
db: DbOption,
638+
639+
#[arg(long)]
640+
a_id: String,
641+
642+
#[arg(long)]
643+
b_id: String,
644+
},
631645
}
632646

633647
#[derive(Debug, clap::Parser)]
@@ -1187,6 +1201,105 @@ Make sure to modify `{dir}/perf-config.json` if the category/artifact don't matc
11871201
println!("Data of artifact {name} were removed");
11881202
Ok(0)
11891203
}
1204+
Commands::BenchLocalDiff { db, a_id, b_id } => {
1205+
let pool = Pool::open(&db.db);
1206+
let rt = build_async_runtime();
1207+
let mut conn = rt.block_on(pool.connection());
1208+
let index = rt.block_on(database::Index::load(&mut *conn));
1209+
1210+
let sids = index
1211+
.compile_statistic_descriptions()
1212+
.map(|(_, sid)| sid)
1213+
.collect::<Vec<_>>();
1214+
1215+
let a_id_number = rt
1216+
.block_on(conn.artifact_by_name(&a_id))
1217+
.expect("Cannot find specified artifact")
1218+
.lookup(&index)
1219+
.unwrap();
1220+
let b_id_number = rt
1221+
.block_on(conn.artifact_by_name(&b_id))
1222+
.expect("Cannot find specified artifact")
1223+
.lookup(&index)
1224+
.unwrap();
1225+
1226+
let pstats =
1227+
rt.block_on(conn.get_pstats(&sids, &[Some(a_id_number), Some(b_id_number)]));
1228+
let tuple_pstats = pstats
1229+
.into_iter()
1230+
.map(|row| row.into_iter().collect_tuple::<(_, _)>().unwrap())
1231+
.collect::<Vec<(Option<f64>, Option<f64>)>>();
1232+
1233+
#[derive(Tabled)]
1234+
struct Regression {
1235+
count: usize,
1236+
#[tabled(display_with = "display_range")]
1237+
range: (f64, f64),
1238+
#[tabled(display_with = "display_mean")]
1239+
mean: f64,
1240+
}
1241+
1242+
fn display_range(value: &(f64, f64)) -> String {
1243+
format!("[{:+.2}%, {:+.2}%]", value.0, value.1)
1244+
}
1245+
1246+
fn display_mean(value: &f64) -> String {
1247+
format!("{:+.2}%", value)
1248+
}
1249+
1250+
impl From<&Vec<f64>> for Regression {
1251+
fn from(value: &Vec<f64>) -> Self {
1252+
let min = *value.iter().min_by(|a, b| a.total_cmp(b)).unwrap();
1253+
let max = *value.iter().max_by(|a, b| a.total_cmp(b)).unwrap();
1254+
let count = value.len();
1255+
1256+
Regression {
1257+
range: (min, max),
1258+
count,
1259+
mean: (value.iter().sum::<f64>() / count as f64) * 100.0,
1260+
}
1261+
}
1262+
}
1263+
1264+
let change = tuple_pstats
1265+
.iter()
1266+
.filter_map(|&(a, b)| match (a, b) {
1267+
(Some(a), Some(b)) => Some(if a == 0.0 { 0.0 } else { (b - a) / a }),
1268+
(_, _) => None,
1269+
})
1270+
.collect::<Vec<_>>();
1271+
let negative_change = change
1272+
.iter()
1273+
.copied()
1274+
.filter(|&c| c < 0.0)
1275+
.collect::<Vec<_>>();
1276+
let positive_change = change
1277+
.iter()
1278+
.copied()
1279+
.filter(|&c| c > 0.0)
1280+
.collect::<Vec<_>>();
1281+
1282+
#[derive(Tabled)]
1283+
struct NamedRegression {
1284+
name: String,
1285+
#[tabled(inline)]
1286+
regression: Regression,
1287+
}
1288+
1289+
let regressions = [negative_change, positive_change, change]
1290+
.into_iter()
1291+
.map(|c| Regression::from(&c))
1292+
.zip(["❌", "✅", "✅, ❌"])
1293+
.map(|(c, label)| NamedRegression {
1294+
name: label.to_string(),
1295+
regression: c,
1296+
})
1297+
.collect::<Vec<_>>();
1298+
1299+
println!("{}", Table::new(regressions));
1300+
1301+
Ok(0)
1302+
}
11901303
}
11911304
}
11921305

@@ -1736,7 +1849,6 @@ fn bench_compile(
17361849
category,
17371850
));
17381851
print_intro();
1739-
17401852
let mut processor = BenchProcessor::new(
17411853
tx.conn(),
17421854
benchmark_name,

0 commit comments

Comments
 (0)