11use crate :: api:: github:: Issue ;
2- use crate :: comparison:: { write_summary_table, ComparisonSummary , Direction } ;
2+ use crate :: comparison:: { write_summary_table, ComparisonSummary , Direction , Magnitude } ;
33use crate :: load:: { Config , SiteCtxt , TryCommit } ;
44
55use anyhow:: Context as _;
@@ -558,154 +558,154 @@ pub async fn post_finished(ctxt: &SiteCtxt) {
558558///
559559/// `is_master_commit` is used to differentiate messages for try runs and post-merge runs.
560560async fn post_comparison_comment ( ctxt : & SiteCtxt , commit : QueuedCommit , is_master_commit : bool ) {
561+ let pr = commit. pr ;
562+ let body = summarize_run ( ctxt, commit, is_master_commit) . await ;
563+
564+ post_comment ( & ctxt. config , pr, body) . await ;
565+ }
566+
567+ async fn summarize_run ( ctxt : & SiteCtxt , commit : QueuedCommit , is_master_commit : bool ) -> String {
561568 let comparison_url = format ! (
562569 "https://perf.rust-lang.org/compare.html?start={}&end={}" ,
563570 commit. parent_sha, commit. sha
564571 ) ;
565- let ( summary, direction) =
566- categorize_benchmark ( ctxt, commit. sha . clone ( ) , commit. parent_sha ) . await ;
572+ let comparison = match crate :: comparison:: compare (
573+ collector:: Bound :: Commit ( commit. parent_sha ) ,
574+ collector:: Bound :: Commit ( commit. sha . clone ( ) ) ,
575+ "instructions:u" . to_owned ( ) ,
576+ ctxt,
577+ )
578+ . await
579+ {
580+ Ok ( Some ( c) ) => c,
581+ _ => return String :: from ( "ERROR categorizing benchmark run!" ) ,
582+ } ;
583+
584+ let errors = if !comparison. newly_failed_benchmarks . is_empty ( ) {
585+ let benchmarks = comparison
586+ . newly_failed_benchmarks
587+ . iter ( )
588+ . map ( |( benchmark, _) | format ! ( "- {benchmark}" ) )
589+ . collect :: < Vec < _ > > ( )
590+ . join ( "\n " ) ;
591+ format ! ( "\n **Warning ⚠**: The following benchmark(s) failed to build:\n {benchmarks}\n " )
592+ } else {
593+ String :: new ( )
594+ } ;
595+
596+ let benchmark_map = ctxt. get_benchmark_category_map ( ) . await ;
597+ let ( primary, secondary) = comparison. summarize_by_category ( benchmark_map) ;
598+
599+ const DISAGREEMENT : & str = "If you disagree with this performance assessment, \
600+ please file an issue in [rust-lang/rustc-perf](https://github.com/rust-lang/rustc-perf/issues/new).";
601+ let footer = format ! ( "{DISAGREEMENT}{errors}" ) ;
602+
603+ if !primary. is_relevant ( ) && !secondary. is_relevant ( ) {
604+ return format ! ( "This benchmark run did not return any relevant results.\n \n {footer}" ) ;
605+ }
606+
607+ let primary_short_summary = generate_short_summary ( & primary) ;
608+ let secondary_short_summary = generate_short_summary ( & secondary) ;
609+
610+ let mut summary = format ! (
611+ r#"
612+ - Primary benchmarks: {primary_short_summary}
613+ - Secondary benchmarks: {secondary_short_summary}
614+ "#
615+ ) ;
616+ write ! ( summary, "\n \n " ) . unwrap ( ) ;
617+
618+ write_summary_table ( & primary, & secondary, true , & mut summary) ;
567619
568- let body = format ! (
569- "Finished benchmarking commit ({sha}): [comparison url]({url}).
620+ write ! ( summary, "\n {footer}" ) . unwrap ( ) ;
621+
622+ let direction = primary. direction ( ) . or ( secondary. direction ( ) ) ;
623+ let next_steps = next_steps ( primary, secondary, direction, is_master_commit) ;
624+
625+ format ! (
626+ "Finished benchmarking commit ({sha}): [comparison url]({comparison_url}).
570627
571628**Summary**: {summary}
572- {rest }" ,
629+ {next_steps }" ,
573630 sha = commit. sha,
574- url = comparison_url,
575- summary = summary,
576- rest = if is_master_commit {
577- master_run_body( direction)
578- } else {
579- try_run_body( direction)
631+ )
632+ }
633+
634+ fn next_steps (
635+ primary : ComparisonSummary ,
636+ secondary : ComparisonSummary ,
637+ direction : Option < Direction > ,
638+ is_master_commit : bool ,
639+ ) -> String {
640+ // whether we are confident enough this is a real change and it deserves to be looked at
641+ let deserves_attention = match ( primary. largest_change ( ) , secondary. largest_change ( ) ) {
642+ ( Some ( c) , _) if c. magnitude ( ) >= Magnitude :: Medium => true ,
643+ ( _, Some ( c) ) if c. magnitude ( ) >= Magnitude :: Medium => true ,
644+ _ => {
645+ let primary_n = primary. num_changes ( ) ;
646+ let secondary_n = secondary. num_changes ( ) ;
647+ ( primary_n * 2 + secondary_n) >= 6
580648 }
581- ) ;
649+ } ;
650+ let label = match ( deserves_attention, direction) {
651+ ( true , Some ( Direction :: Regression | Direction :: Mixed ) ) => "+perf-regression" ,
652+ _ => "-perf-regression" ,
653+ } ;
582654
583- post_comment ( & ctxt. config , commit. pr , body) . await ;
655+ if is_master_commit {
656+ master_run_body ( label)
657+ } else {
658+ try_run_body ( label)
659+ }
584660}
585661
586- fn master_run_body ( direction : Option < Direction > ) -> String {
587- let label = match direction {
588- Some ( Direction :: Regression | Direction :: Mixed ) => "+perf-regression" ,
589- Some ( Direction :: Improvement ) | None => "-perf-regression" ,
590- } ;
591- let next_steps = match direction {
592- Some ( Direction :: Regression | Direction :: Mixed ) => {
593- "\n \n **Next Steps**: If you can justify the \
662+ fn master_run_body ( label : & str ) -> String {
663+ let next_steps = if label. starts_with ( "+" ) {
664+ "\n \n **Next Steps**: If you can justify the \
594665 regressions found in this perf run, please indicate this with \
595666 `@rustbot label: +perf-regression-triaged` along with \
596667 sufficient written justification. If you cannot justify the regressions \
597668 please open an issue or create a new PR that fixes the regressions, \
598669 add a comment linking to the newly created issue or PR, \
599670 and then add the `perf-regression-triaged` label to this PR."
600- }
601- Some ( Direction :: Improvement ) | None => "" ,
671+ } else {
672+ ""
602673 } ;
603674
604675 format ! (
605676 "
606677{next_steps}
607678
608679@rustbot label: {label}" ,
609- next_steps = next_steps,
610- label = label
611680 )
612681}
613682
614- fn try_run_body ( direction : Option < Direction > ) -> String {
615- let label = match direction {
616- Some ( Direction :: Regression | Direction :: Mixed ) => "+perf-regression" ,
617- Some ( Direction :: Improvement ) | None => "-perf-regression" ,
618- } ;
619- let next_steps = match direction {
620- Some ( Direction :: Regression | Direction :: Mixed ) => {
621- "\n \n **Next Steps**: If you can justify the regressions found in \
683+ fn try_run_body ( label : & str ) -> String {
684+ let next_steps = if label. starts_with ( "+" ) {
685+ "\n \n **Next Steps**: If you can justify the regressions found in \
622686 this try perf run, please indicate this with \
623687 `@rustbot label: +perf-regression-triaged` along with \
624688 sufficient written justification. If you cannot justify the regressions \
625689 please fix the regressions and do another perf run. If the next run \
626690 shows neutral or positive results, the label will be automatically removed."
627- }
628- Some ( Direction :: Improvement ) | None => "" ,
691+ } else {
692+ ""
629693 } ;
630694
631695 format ! (
632696 "
633697Benchmarking this pull request likely means that it is \
634698 perf-sensitive, so we're automatically marking it as not fit \
635699 for rolling up. While you can manually mark this PR as fit \
636- for rollup, we strongly recommend not doing so since this PR led to changes in \
700+ for rollup, we strongly recommend not doing so since this PR may lead to changes in \
637701 compiler perf.{next_steps}
638702
639703@bors rollup=never
640704@rustbot label: +S-waiting-on-review -S-waiting-on-perf {label}" ,
641- next_steps = next_steps,
642- label = label
643705 )
644706}
645707
646- async fn categorize_benchmark (
647- ctxt : & SiteCtxt ,
648- commit_sha : String ,
649- parent_sha : String ,
650- ) -> ( String , Option < Direction > ) {
651- let comparison = match crate :: comparison:: compare (
652- collector:: Bound :: Commit ( parent_sha) ,
653- collector:: Bound :: Commit ( commit_sha) ,
654- "instructions:u" . to_owned ( ) ,
655- ctxt,
656- )
657- . await
658- {
659- Ok ( Some ( c) ) => c,
660- _ => return ( String :: from ( "ERROR categorizing benchmark run!" ) , None ) ,
661- } ;
662-
663- let errors = if !comparison. newly_failed_benchmarks . is_empty ( ) {
664- let benchmarks = comparison
665- . newly_failed_benchmarks
666- . iter ( )
667- . map ( |( benchmark, _) | format ! ( "- {benchmark}" ) )
668- . collect :: < Vec < _ > > ( )
669- . join ( "\n " ) ;
670- format ! ( "\n **Warning ⚠**: The following benchmark(s) failed to build:\n {benchmarks}\n " )
671- } else {
672- String :: new ( )
673- } ;
674-
675- let benchmark_map = ctxt. get_benchmark_category_map ( ) . await ;
676- let ( primary, secondary) = comparison. summarize_by_category ( benchmark_map) ;
677-
678- const DISAGREEMENT : & str = "If you disagree with this performance assessment, \
679- please file an issue in [rust-lang/rustc-perf](https://github.com/rust-lang/rustc-perf/issues/new).";
680- let footer = format ! ( "{DISAGREEMENT}{errors}" ) ;
681-
682- if !primary. is_relevant ( ) && !secondary. is_relevant ( ) {
683- return (
684- format ! ( "This benchmark run did not return any relevant results.\n \n {footer}" ) ,
685- None ,
686- ) ;
687- }
688-
689- let ( primary_short_summary, primary_direction) = generate_short_summary ( & primary) ;
690- let ( secondary_short_summary, secondary_direction) = generate_short_summary ( & secondary) ;
691-
692- let mut result = format ! (
693- r#"
694- - Primary benchmarks: {primary_short_summary}
695- - Secondary benchmarks: {secondary_short_summary}
696- "#
697- ) ;
698- write ! ( result, "\n \n " ) . unwrap ( ) ;
699-
700- write_summary_table ( & primary, & secondary, true , & mut result) ;
701-
702- write ! ( result, "\n {footer}" ) . unwrap ( ) ;
703-
704- let direction = primary_direction. or ( secondary_direction) ;
705- ( result, direction)
706- }
707-
708- fn generate_short_summary ( summary : & ComparisonSummary ) -> ( String , Option < Direction > ) {
708+ fn generate_short_summary ( summary : & ComparisonSummary ) -> String {
709709 // Add an "s" to a word unless there's only one.
710710 fn ending ( word : & ' static str , count : usize ) -> std:: borrow:: Cow < ' static , str > {
711711 if count == 1 {
@@ -714,25 +714,20 @@ fn generate_short_summary(summary: &ComparisonSummary) -> (String, Option<Direct
714714 format ! ( "{}s" , word) . into ( )
715715 }
716716
717- if summary. is_relevant ( ) {
718- let direction = summary. direction ( ) . unwrap ( ) ;
719- let num_improvements = summary. number_of_improvements ( ) ;
720- let num_regressions = summary. number_of_regressions ( ) ;
717+ let num_improvements = summary. number_of_improvements ( ) ;
718+ let num_regressions = summary. number_of_regressions ( ) ;
721719
722- let text = match direction {
723- Direction :: Improvement => format ! (
724- "🎉 relevant {} found" ,
725- ending( "improvement" , num_improvements)
726- ) ,
727- Direction :: Regression => format ! (
728- "😿 relevant {} found" ,
729- ending( "regression" , num_regressions)
730- ) ,
731- Direction :: Mixed => "mixed results" . to_string ( ) ,
732- } ;
733- ( text, Some ( direction) )
734- } else {
735- ( "no relevant changes found" . to_string ( ) , None )
720+ match summary. direction ( ) {
721+ Some ( Direction :: Improvement ) => format ! (
722+ "🎉 relevant {} found" ,
723+ ending( "improvement" , num_improvements)
724+ ) ,
725+ Some ( Direction :: Regression ) => format ! (
726+ "😿 relevant {} found" ,
727+ ending( "regression" , num_regressions)
728+ ) ,
729+ Some ( Direction :: Mixed ) => "mixed results" . to_string ( ) ,
730+ None => "no relevant changes found" . to_string ( ) ,
736731 }
737732}
738733
0 commit comments