Skip to content

Commit d20abeb

Browse files
committed
split bench_cmp's logic to src/compare.rs
1 parent 671a368 commit d20abeb

File tree

3 files changed

+118
-108
lines changed

3 files changed

+118
-108
lines changed

Diff for: collector/src/bin/collector.rs

+7-108
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,12 @@ use std::{str, time::Instant};
1818
use anyhow::Context;
1919
use clap::builder::TypedValueParser;
2020
use clap::{Arg, Parser};
21+
use collector::compare::compare_artifacts;
2122
use humansize::{format_size, BINARY};
22-
use itertools::Itertools;
2323
use rayon::iter::{IndexedParallelIterator, IntoParallelRefIterator, ParallelIterator};
2424
use tabled::builder::Builder;
2525
use tabled::settings::object::{Columns, Rows};
2626
use tabled::settings::{Alignment, Border, Color, Modify};
27-
use tabled::{Table, Tabled};
2827
use tokio::runtime::Runtime;
2928

3029
use collector::api::next_artifact::NextArtifact;
@@ -54,7 +53,7 @@ use collector::toolchain::{
5453
use collector::utils::cachegrind::cachegrind_diff;
5554
use collector::utils::{is_installed, wait_for_future};
5655
use collector::{utils, CollectorCtx, CollectorStepBuilder};
57-
use database::{ArtifactId, ArtifactIdNumber, Commit, CommitType, Connection, Lookup, Pool};
56+
use database::{ArtifactId, ArtifactIdNumber, Commit, CommitType, Connection, Pool};
5857

5958
fn n_normal_benchmarks_remaining(n: usize) -> String {
6059
let suffix = if n == 1 { "" } else { "s" };
@@ -637,10 +636,10 @@ enum Commands {
637636
db: DbOption,
638637

639638
#[arg(long)]
640-
a_id: String,
639+
base: String,
641640

642641
#[arg(long)]
643-
b_id: String,
642+
modified: String,
644643
},
645644
}
646645

@@ -1201,111 +1200,11 @@ Make sure to modify `{dir}/perf-config.json` if the category/artifact don't matc
12011200
println!("Data of artifact {name} were removed");
12021201
Ok(0)
12031202
}
1204-
Commands::BenchLocalDiff { db, a_id, b_id } => {
1203+
Commands::BenchLocalDiff { db, base, modified } => {
12051204
let pool = Pool::open(&db.db);
12061205
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),
1260-
}
1261-
}
1262-
}
1263-
1264-
const DEFAULT_SIGNIFICANCE_THRESHOLD: f64 = 0.002;
1265-
let change = tuple_pstats
1266-
.iter()
1267-
.filter_map(|&(a, b)| match (a, b) {
1268-
(Some(a), Some(b)) => {
1269-
if a == 0.0 {
1270-
None
1271-
} else {
1272-
Some((b - a) / a)
1273-
}
1274-
}
1275-
(_, _) => None,
1276-
})
1277-
.filter(|c| c.abs() >= DEFAULT_SIGNIFICANCE_THRESHOLD * 100.0)
1278-
.collect::<Vec<_>>();
1279-
let negative_change = change
1280-
.iter()
1281-
.copied()
1282-
.filter(|&c| c < 0.0)
1283-
.collect::<Vec<_>>();
1284-
let positive_change = change
1285-
.iter()
1286-
.copied()
1287-
.filter(|&c| c > 0.0)
1288-
.collect::<Vec<_>>();
1289-
1290-
#[derive(Tabled)]
1291-
struct NamedRegression {
1292-
name: String,
1293-
#[tabled(inline)]
1294-
regression: Regression,
1295-
}
1296-
1297-
let regressions = [negative_change, positive_change, change]
1298-
.into_iter()
1299-
.map(|c| Regression::from(&c))
1300-
.zip(["❌", "✅", "✅, ❌"])
1301-
.map(|(c, label)| NamedRegression {
1302-
name: label.to_string(),
1303-
regression: c,
1304-
})
1305-
.collect::<Vec<_>>();
1306-
1307-
println!("{}", Table::new(regressions));
1308-
1206+
let conn = rt.block_on(pool.connection());
1207+
rt.block_on(compare_artifacts(conn, base, modified));
13091208
Ok(0)
13101209
}
13111210
}

Diff for: collector/src/compare.rs

+110
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
use database::{Connection, Lookup};
2+
use itertools::Itertools;
3+
use tabled::{Table, Tabled};
4+
5+
const DEFAULT_SIGNIFICANCE_THRESHOLD: f64 = 0.002;
6+
7+
/// Compare 2 artifacts and print the result.
8+
pub async fn compare_artifacts(mut conn: Box<dyn Connection>, base: String, modified: String) {
9+
let index = database::Index::load(&mut *conn).await;
10+
let sids = index
11+
.compile_statistic_descriptions()
12+
.map(|(_, sid)| sid)
13+
.collect::<Vec<_>>();
14+
15+
let base_id_number = conn
16+
.artifact_by_name(&base)
17+
.await
18+
.expect("Cannot find specified artifact")
19+
.lookup(&index)
20+
.unwrap();
21+
let modified_id_number = conn
22+
.artifact_by_name(&modified)
23+
.await
24+
.expect("Cannot find specified artifact")
25+
.lookup(&index)
26+
.unwrap();
27+
28+
let pstats = conn
29+
.get_pstats(&sids, &[Some(base_id_number), Some(modified_id_number)])
30+
.await;
31+
let tuple_pstats = pstats
32+
.into_iter()
33+
.map(|row| row.into_iter().collect_tuple::<(_, _)>().unwrap())
34+
.collect::<Vec<(Option<f64>, Option<f64>)>>();
35+
36+
#[derive(Tabled)]
37+
struct Regression {
38+
count: usize,
39+
#[tabled(display_with = "display_range")]
40+
range: (f64, f64),
41+
#[tabled(display_with = "display_mean")]
42+
mean: f64,
43+
}
44+
45+
fn display_range(value: &(f64, f64)) -> String {
46+
format!("[{:+.2}%, {:+.2}%]", value.0, value.1)
47+
}
48+
49+
fn display_mean(value: &f64) -> String {
50+
format!("{:+.2}%", value)
51+
}
52+
53+
impl From<&Vec<f64>> for Regression {
54+
fn from(value: &Vec<f64>) -> Self {
55+
let min = *value.iter().min_by(|a, b| a.total_cmp(b)).unwrap();
56+
let max = *value.iter().max_by(|a, b| a.total_cmp(b)).unwrap();
57+
let count = value.len();
58+
59+
Regression {
60+
range: (min, max),
61+
count,
62+
mean: (value.iter().sum::<f64>() / count as f64),
63+
}
64+
}
65+
}
66+
67+
let change = tuple_pstats
68+
.iter()
69+
.filter_map(|&(a, b)| match (a, b) {
70+
(Some(a), Some(b)) => {
71+
if a == 0.0 {
72+
None
73+
} else {
74+
Some((b - a) / a)
75+
}
76+
}
77+
(_, _) => None,
78+
})
79+
.filter(|c| c.abs() >= DEFAULT_SIGNIFICANCE_THRESHOLD * 100.0)
80+
.collect::<Vec<_>>();
81+
let negative_change = change
82+
.iter()
83+
.copied()
84+
.filter(|&c| c < 0.0)
85+
.collect::<Vec<_>>();
86+
let positive_change = change
87+
.iter()
88+
.copied()
89+
.filter(|&c| c > 0.0)
90+
.collect::<Vec<_>>();
91+
92+
#[derive(Tabled)]
93+
struct NamedRegression {
94+
name: String,
95+
#[tabled(inline)]
96+
regression: Regression,
97+
}
98+
99+
let regressions = [negative_change, positive_change, change]
100+
.into_iter()
101+
.map(|c| Regression::from(&c))
102+
.zip(["❌", "✅", "✅, ❌"])
103+
.map(|(c, label)| NamedRegression {
104+
name: label.to_string(),
105+
regression: c,
106+
})
107+
.collect::<Vec<_>>();
108+
109+
println!("{}", Table::new(regressions));
110+
}

Diff for: collector/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ pub mod api;
99
pub mod artifact_stats;
1010
pub mod cargo;
1111
pub mod codegen;
12+
pub mod compare;
1213
pub mod compile;
1314
pub mod runtime;
1415
pub mod toolchain;

0 commit comments

Comments
 (0)