1 use std::process::Child;
2 
3 use criterion_plot::prelude::*;
4 
5 use super::*;
6 use crate::report::{BenchmarkId, ComparisonData, MeasurementData, ReportContext};
7 
8 use crate::measurement::ValueFormatter;
9 
iteration_times_figure( formatter: &dyn ValueFormatter, measurements: &MeasurementData<'_>, size: Option<Size>, ) -> Figure10 fn iteration_times_figure(
11     formatter: &dyn ValueFormatter,
12     measurements: &MeasurementData<'_>,
13     size: Option<Size>,
14 ) -> Figure {
15     let data = &measurements.avg_times;
16     let max_avg_time = data.max();
17     let mut scaled_y: Vec<_> = data.iter().map(|(f, _)| f).collect();
18     let unit = formatter.scale_values(max_avg_time, &mut scaled_y);
19     let scaled_y = Sample::new(&scaled_y);
20 
21     let mut figure = Figure::new();
22     figure
23         .set(Font(DEFAULT_FONT))
24         .set(size.unwrap_or(SIZE))
25         .configure(Axis::BottomX, |a| {
26             a.configure(Grid::Major, |g| g.show()).set(Label("Sample"))
27         })
28         .configure(Axis::LeftY, |a| {
29             a.configure(Grid::Major, |g| g.show())
30                 .set(Label(format!("Average Iteration Time ({})", unit)))
31         })
32         .plot(
33             Points {
34                 x: 1..(data.len() + 1),
35                 y: scaled_y.as_ref(),
36             },
37             |c| {
38                 c.set(DARK_BLUE)
39                     .set(PointSize(0.5))
40                     .set(PointType::FilledCircle)
41             },
42         );
43     figure
44 }
45 
iteration_times( id: &BenchmarkId, context: &ReportContext, formatter: &dyn ValueFormatter, measurements: &MeasurementData<'_>, size: Option<Size>, ) -> Child46 pub(crate) fn iteration_times(
47     id: &BenchmarkId,
48     context: &ReportContext,
49     formatter: &dyn ValueFormatter,
50     measurements: &MeasurementData<'_>,
51     size: Option<Size>,
52 ) -> Child {
53     let mut figure = iteration_times_figure(formatter, measurements, size);
54     figure.set(Title(gnuplot_escape(id.as_title())));
55     figure.configure(Key, |k| {
56         k.set(Justification::Left)
57             .set(Order::SampleText)
58             .set(Position::Inside(Vertical::Top, Horizontal::Left))
59     });
60 
61     let path = context.report_path(id, "iteration_times.svg");
62     debug_script(&path, &figure);
63     figure.set(Output(path)).draw().unwrap()
64 }
65 
iteration_times_small( id: &BenchmarkId, context: &ReportContext, formatter: &dyn ValueFormatter, measurements: &MeasurementData<'_>, size: Option<Size>, ) -> Child66 pub(crate) fn iteration_times_small(
67     id: &BenchmarkId,
68     context: &ReportContext,
69     formatter: &dyn ValueFormatter,
70     measurements: &MeasurementData<'_>,
71     size: Option<Size>,
72 ) -> Child {
73     let mut figure = iteration_times_figure(formatter, measurements, size);
74     figure.configure(Key, |k| k.hide());
75 
76     let path = context.report_path(id, "iteration_times_small.svg");
77     debug_script(&path, &figure);
78     figure.set(Output(path)).draw().unwrap()
79 }
80 
iteration_times_comparison_figure( formatter: &dyn ValueFormatter, measurements: &MeasurementData<'_>, comparison: &ComparisonData, size: Option<Size>, ) -> Figure81 fn iteration_times_comparison_figure(
82     formatter: &dyn ValueFormatter,
83     measurements: &MeasurementData<'_>,
84     comparison: &ComparisonData,
85     size: Option<Size>,
86 ) -> Figure {
87     let current_data = &measurements.avg_times;
88     let base_data = &comparison.base_avg_times;
89 
90     let mut all_data: Vec<f64> = current_data.iter().map(|(f, _)| f).collect();
91     all_data.extend_from_slice(base_data);
92 
93     let typical_value = Sample::new(&all_data).max();
94     let unit = formatter.scale_values(typical_value, &mut all_data);
95 
96     let (scaled_current_y, scaled_base_y) = all_data.split_at(current_data.len());
97     let scaled_current_y = Sample::new(scaled_current_y);
98     let scaled_base_y = Sample::new(scaled_base_y);
99 
100     let mut figure = Figure::new();
101     figure
102         .set(Font(DEFAULT_FONT))
103         .set(size.unwrap_or(SIZE))
104         .configure(Axis::BottomX, |a| {
105             a.configure(Grid::Major, |g| g.show()).set(Label("Sample"))
106         })
107         .configure(Axis::LeftY, |a| {
108             a.configure(Grid::Major, |g| g.show())
109                 .set(Label(format!("Average Iteration Time ({})", unit)))
110         })
111         .configure(Key, |k| {
112             k.set(Justification::Left)
113                 .set(Order::SampleText)
114                 .set(Position::Inside(Vertical::Top, Horizontal::Left))
115         })
116         .plot(
117             Points {
118                 x: 1..(current_data.len() + 1),
119                 y: scaled_base_y.as_ref(),
120             },
121             |c| {
122                 c.set(DARK_RED)
123                     .set(Label("Base"))
124                     .set(PointSize(0.5))
125                     .set(PointType::FilledCircle)
126             },
127         )
128         .plot(
129             Points {
130                 x: 1..(current_data.len() + 1),
131                 y: scaled_current_y.as_ref(),
132             },
133             |c| {
134                 c.set(DARK_BLUE)
135                     .set(Label("Current"))
136                     .set(PointSize(0.5))
137                     .set(PointType::FilledCircle)
138             },
139         );
140     figure
141 }
142 
iteration_times_comparison( id: &BenchmarkId, context: &ReportContext, formatter: &dyn ValueFormatter, measurements: &MeasurementData<'_>, comparison: &ComparisonData, size: Option<Size>, ) -> Child143 pub(crate) fn iteration_times_comparison(
144     id: &BenchmarkId,
145     context: &ReportContext,
146     formatter: &dyn ValueFormatter,
147     measurements: &MeasurementData<'_>,
148     comparison: &ComparisonData,
149     size: Option<Size>,
150 ) -> Child {
151     let mut figure = iteration_times_comparison_figure(formatter, measurements, comparison, size);
152     figure.set(Title(gnuplot_escape(id.as_title())));
153 
154     let path = context.report_path(id, "both/iteration_times.svg");
155     debug_script(&path, &figure);
156     figure.set(Output(path)).draw().unwrap()
157 }
158 
iteration_times_comparison_small( id: &BenchmarkId, context: &ReportContext, formatter: &dyn ValueFormatter, measurements: &MeasurementData<'_>, comparison: &ComparisonData, size: Option<Size>, ) -> Child159 pub(crate) fn iteration_times_comparison_small(
160     id: &BenchmarkId,
161     context: &ReportContext,
162     formatter: &dyn ValueFormatter,
163     measurements: &MeasurementData<'_>,
164     comparison: &ComparisonData,
165     size: Option<Size>,
166 ) -> Child {
167     let mut figure = iteration_times_comparison_figure(formatter, measurements, comparison, size);
168     figure.configure(Key, |k| k.hide());
169 
170     let path = context.report_path(id, "relative_iteration_times_small.svg");
171     debug_script(&path, &figure);
172     figure.set(Output(path)).draw().unwrap()
173 }
174