Skip to content

Commit 931ac43

Browse files
authored
Merge pull request #881 from rylev/categorize-perf-runs
Categorize perf runs when posting to GitHub
2 parents 8e06f36 + 499c86c commit 931ac43

File tree

2 files changed

+114
-50
lines changed

2 files changed

+114
-50
lines changed

site/src/comparison.rs

Lines changed: 63 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ pub async fn handle_triage(
2525
let end = body.end;
2626
// Compare against self to get next
2727
let master_commits = collector::master_commits().await?;
28-
let comparison = compare(
28+
let comparison = compare_given_commits(
2929
start.clone(),
3030
start.clone(),
3131
"instructions:u".to_owned(),
@@ -40,7 +40,7 @@ pub async fn handle_triage(
4040
let mut before = start.clone();
4141

4242
loop {
43-
let comparison = match compare(
43+
let comparison = match compare_given_commits(
4444
before,
4545
after.clone(),
4646
"instructions:u".to_owned(),
@@ -87,16 +87,17 @@ pub async fn handle_compare(
8787
body: api::days::Request,
8888
data: &InputData,
8989
) -> Result<api::days::Response, BoxedError> {
90-
let commits = collector::master_commits().await?;
90+
let master_commits = collector::master_commits().await?;
9191
let end = body.end;
92-
let comparison = crate::comparison::compare(body.start, end.clone(), body.stat, data, &commits)
93-
.await?
94-
.ok_or_else(|| format!("could not find end commit for bound {:?}", end))?;
92+
let comparison =
93+
compare_given_commits(body.start, end.clone(), body.stat, data, &master_commits)
94+
.await?
95+
.ok_or_else(|| format!("could not find end commit for bound {:?}", end))?;
9596

9697
let conn = data.conn().await;
97-
let prev = comparison.prev(&commits);
98-
let next = comparison.next(&commits);
99-
let is_contiguous = comparison.is_contiguous(&*conn, &commits).await;
98+
let prev = comparison.prev(&master_commits);
99+
let next = comparison.next(&master_commits);
100+
let is_contiguous = comparison.is_contiguous(&*conn, &master_commits).await;
100101

101102
Ok(api::days::Response {
102103
prev,
@@ -108,7 +109,7 @@ pub async fn handle_compare(
108109
}
109110

110111
async fn populate_report(comparison: &Comparison, report: &mut HashMap<Direction, Vec<String>>) {
111-
if let Some(summary) = summarize_comparison(comparison) {
112+
if let Some(summary) = ComparisonSummary::summarize_comparison(comparison) {
112113
if let Some(direction) = summary.direction() {
113114
let entry = report.entry(direction).or_default();
114115

@@ -117,44 +118,44 @@ async fn populate_report(comparison: &Comparison, report: &mut HashMap<Direction
117118
}
118119
}
119120

120-
fn summarize_comparison<'a>(comparison: &'a Comparison) -> Option<ComparisonSummary<'a>> {
121-
let mut benchmarks = comparison.get_benchmarks();
122-
// Skip empty commits, sometimes happens if there's a compiler bug or so.
123-
if benchmarks.len() == 0 {
124-
return None;
125-
}
126-
127-
let cmp = |b1: &BenchmarkComparison, b2: &BenchmarkComparison| {
128-
b1.log_change()
129-
.partial_cmp(&b2.log_change())
130-
.unwrap_or(std::cmp::Ordering::Equal)
131-
};
132-
let lo = benchmarks
133-
.iter()
134-
.enumerate()
135-
.min_by(|&(_, b1), &(_, b2)| cmp(b1, b2))
136-
.filter(|(_, c)| c.is_significant() && !c.is_increase())
137-
.map(|(i, _)| i);
138-
let lo = lo.map(|lo| benchmarks.remove(lo));
139-
let hi = benchmarks
140-
.iter()
141-
.enumerate()
142-
.max_by(|&(_, b1), &(_, b2)| cmp(b1, b2))
143-
.filter(|(_, c)| c.is_significant() && c.is_increase())
144-
.map(|(i, _)| i);
145-
let hi = hi.map(|hi| benchmarks.remove(hi));
146-
147-
Some(ComparisonSummary { hi, lo })
148-
}
149-
150-
struct ComparisonSummary<'a> {
121+
pub struct ComparisonSummary<'a> {
151122
hi: Option<BenchmarkComparison<'a>>,
152123
lo: Option<BenchmarkComparison<'a>>,
153124
}
154125

155126
impl ComparisonSummary<'_> {
127+
pub fn summarize_comparison<'a>(comparison: &'a Comparison) -> Option<ComparisonSummary<'a>> {
128+
let mut benchmarks = comparison.get_benchmarks();
129+
// Skip empty commits, sometimes happens if there's a compiler bug or so.
130+
if benchmarks.len() == 0 {
131+
return None;
132+
}
133+
134+
let cmp = |b1: &BenchmarkComparison, b2: &BenchmarkComparison| {
135+
b1.log_change()
136+
.partial_cmp(&b2.log_change())
137+
.unwrap_or(std::cmp::Ordering::Equal)
138+
};
139+
let lo = benchmarks
140+
.iter()
141+
.enumerate()
142+
.min_by(|&(_, b1), &(_, b2)| cmp(b1, b2))
143+
.filter(|(_, c)| c.is_significant() && !c.is_increase())
144+
.map(|(i, _)| i);
145+
let lo = lo.map(|lo| benchmarks.remove(lo));
146+
let hi = benchmarks
147+
.iter()
148+
.enumerate()
149+
.max_by(|&(_, b1), &(_, b2)| cmp(b1, b2))
150+
.filter(|(_, c)| c.is_significant() && c.is_increase())
151+
.map(|(i, _)| i);
152+
let hi = hi.map(|hi| benchmarks.remove(hi));
153+
154+
Some(ComparisonSummary { hi, lo })
155+
}
156+
156157
/// The direction of the changes
157-
fn direction(&self) -> Option<Direction> {
158+
pub fn direction(&self) -> Option<Direction> {
158159
let d = match (&self.hi, &self.lo) {
159160
(None, None) => return None,
160161
(Some(b), None) => b.direction(),
@@ -166,7 +167,7 @@ impl ComparisonSummary<'_> {
166167
}
167168

168169
/// The changes ordered by their signficance (most significant first)
169-
fn ordered_changes(&self) -> Vec<&BenchmarkComparison<'_>> {
170+
pub fn ordered_changes(&self) -> Vec<&BenchmarkComparison<'_>> {
170171
match (&self.hi, &self.lo) {
171172
(None, None) => Vec::new(),
172173
(Some(b), None) => vec![b],
@@ -202,7 +203,7 @@ impl ComparisonSummary<'_> {
202203

203204
for change in self.ordered_changes() {
204205
write!(result, "- ").unwrap();
205-
change.summary_line(&mut result, link)
206+
change.summary_line(&mut result, Some(link))
206207
}
207208
result
208209
}
@@ -216,6 +217,17 @@ pub async fn compare(
216217
end: Bound,
217218
stat: String,
218219
data: &InputData,
220+
) -> Result<Option<Comparison>, BoxedError> {
221+
let master_commits = collector::master_commits().await?;
222+
compare_given_commits(start, end, stat, data, &master_commits).await
223+
}
224+
225+
/// Compare two bounds on a given stat
226+
pub async fn compare_given_commits(
227+
start: Bound,
228+
end: Bound,
229+
stat: String,
230+
data: &InputData,
219231
master_commits: &[collector::MasterCommit],
220232
) -> Result<Option<Comparison>, BoxedError> {
221233
let a = data
@@ -404,7 +416,7 @@ impl Comparison {
404416

405417
// A single comparison based on benchmark and cache state
406418
#[derive(Debug)]
407-
struct BenchmarkComparison<'a> {
419+
pub struct BenchmarkComparison<'a> {
408420
bench_name: &'a str,
409421
cache_state: &'a str,
410422
results: (f64, f64),
@@ -446,7 +458,7 @@ impl BenchmarkComparison<'_> {
446458
}
447459
}
448460

449-
fn summary_line(&self, summary: &mut String, link: &str) {
461+
pub fn summary_line(&self, summary: &mut String, link: Option<&str>) {
450462
use std::fmt::Write;
451463
let magnitude = self.log_change().abs();
452464
let size = if magnitude > 0.10 {
@@ -467,7 +479,10 @@ impl BenchmarkComparison<'_> {
467479
"{} {} in [instruction counts]({})",
468480
size,
469481
self.direction(),
470-
link
482+
match link {
483+
Some(l) => l,
484+
None => "",
485+
}
471486
)
472487
.unwrap();
473488
writeln!(
@@ -481,7 +496,7 @@ impl BenchmarkComparison<'_> {
481496

482497
// The direction of a performance change
483498
#[derive(PartialEq, Eq, Hash)]
484-
enum Direction {
499+
pub enum Direction {
485500
Improvement,
486501
Regression,
487502
Mixed,

site/src/github.rs

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use serde::Deserialize;
77
use database::ArtifactId;
88
use regex::Regex;
99
use reqwest::header::USER_AGENT;
10-
use std::{sync::Arc, time::Duration};
10+
use std::{fmt::Write, sync::Arc, time::Duration};
1111

1212
lazy_static::lazy_static! {
1313
static ref BODY_TRY_COMMIT: Regex =
@@ -631,12 +631,15 @@ pub async fn post_finished(data: &InputData) {
631631
"https://perf.rust-lang.org/compare.html?start={}&end={}",
632632
commit.parent_sha, commit.sha
633633
);
634+
let summary = categorize_benchmark(&commit, data).await;
634635
post_comment(
635636
&data.config,
636637
commit.pr,
637638
format!(
638639
"Finished benchmarking try commit ({}): [comparison url]({}).
639640
641+
**Summary**: {}
642+
640643
Benchmarking this pull request likely means that it is \
641644
perf-sensitive, so we're automatically marking it as not fit \
642645
for rolling up. Please note that if the perf results are \
@@ -649,10 +652,56 @@ regressions or improvements in the roll up.
649652
650653
@bors rollup=never
651654
@rustbot label: +S-waiting-on-review -S-waiting-on-perf",
652-
commit.sha, comparison_url
655+
commit.sha, comparison_url, summary
653656
),
654657
)
655658
.await;
656659
}
657660
}
658661
}
662+
663+
async fn categorize_benchmark(commit: &database::QueuedCommit, data: &InputData) -> String {
664+
let comparison = match crate::comparison::compare(
665+
collector::Bound::Commit(commit.parent_sha.clone()),
666+
collector::Bound::Commit(commit.sha.clone()),
667+
"instructions:u".to_owned(),
668+
data,
669+
)
670+
.await
671+
{
672+
Ok(Some(c)) => c,
673+
_ => return String::from("ERROR categorizing benchmark run!"),
674+
};
675+
const DISAGREEMENT: &str = "If you disagree with this performance assessment, \
676+
please file an issue in [rust-lang/rustc-perf](https://github.com/rust-lang/rustc-perf/issues/new).";
677+
let (summary, direction) =
678+
match crate::comparison::ComparisonSummary::summarize_comparison(&comparison) {
679+
Some(s) if s.direction().is_some() => {
680+
let direction = s.direction().unwrap();
681+
(s, direction)
682+
}
683+
_ => {
684+
return format!(
685+
"This benchmark run did not return any significant changes.\n\n{}",
686+
DISAGREEMENT
687+
)
688+
}
689+
};
690+
691+
use crate::comparison::Direction;
692+
let category = match direction {
693+
Direction::Improvement => "improvements 🎉",
694+
Direction::Regression => "regressions 😿",
695+
Direction::Mixed => "mixed results 🤷",
696+
};
697+
let mut result = format!(
698+
"This change led to significant {} in compiler performance.\n",
699+
category
700+
);
701+
for change in summary.ordered_changes() {
702+
write!(result, "- ").unwrap();
703+
change.summary_line(&mut result, None)
704+
}
705+
write!(result, "\n{}", DISAGREEMENT).unwrap();
706+
result
707+
}

0 commit comments

Comments
 (0)