summaryrefslogtreecommitdiff
path: root/perf/cairo-perf-chart.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2012-12-29 18:30:48 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2012-12-29 18:30:48 +0000
commitfbd4864995e261a4cfc5e53273b53ce8a22d72db (patch)
tree5511d9c135adf4c2166f70fac01b9e432019943e /perf/cairo-perf-chart.c
parent71028865fae38bf26c45aae72e0a6773a19a640d (diff)
perf/chart: Show the geometric average as an extra column
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'perf/cairo-perf-chart.c')
-rw-r--r--perf/cairo-perf-chart.c112
1 files changed, 111 insertions, 1 deletions
diff --git a/perf/cairo-perf-chart.c b/perf/cairo-perf-chart.c
index a993ce8a9..67bedd4a5 100644
--- a/perf/cairo-perf-chart.c
+++ b/perf/cairo-perf-chart.c
@@ -45,6 +45,7 @@ struct chart {
int width, height;
int num_tests, num_reports;
double min_value, max_value;
+ double *average;
cairo_bool_t use_html;
cairo_bool_t relative;
@@ -142,12 +143,20 @@ find_ranges (struct chart *chart)
int num_tests = 0;
double slow_sum = 0, fast_sum = 0, sum;
int slow_count = 0, fast_count = 0;
+ int *count;
int i;
num_values = 0;
size_values = 64;
values = xmalloc (size_values * sizeof (double));
+ chart->average = xmalloc(chart->num_reports * sizeof(double));
+ count = xmalloc(chart->num_reports * sizeof(int));
+ for (i = 0; i < chart->num_reports; i++) {
+ chart->average[i] = 0;
+ count[i] = 0;
+ }
+
tests = xmalloc (chart->num_reports * sizeof (test_report_t *));
for (i = 0; i < chart->num_reports; i++)
tests[i] = chart->reports[i].tests;
@@ -202,6 +211,9 @@ find_ranges (struct chart *chart)
if (test_time == 0)
test_time = report_time;
+ chart->average[i] += report_time / test_time;
+ count[i]++;
+
if (chart->relative) {
if (test_time != report_time) {
double v = to_factor (test_time / report_time);
@@ -232,14 +244,22 @@ find_ranges (struct chart *chart)
}
}
+ for (i = 0; i < chart->num_reports; i++) {
+ if (count[i])
+ chart->average[i] = count[i] / chart->average[i];
+ else
+ chart->average[i] = 1.;
+ }
+
if (chart->relative)
trim_outliers (values, num_values, &min, &max);
chart->min_value = min;
chart->max_value = max;
- chart->num_tests = num_tests;
+ chart->num_tests = num_tests + !!chart->relative;
free (values);
free (tests);
+ free (count);
printf ("%d: slow[%d] average: %f, fast[%d] average: %f, %f\n",
num_values, slow_count, slow_sum / slow_count, fast_count, fast_sum / fast_count, sum / num_values);
@@ -451,6 +471,91 @@ add_chart (struct chart *c,
}
static void
+add_average (struct chart *c,
+ int test,
+ int report,
+ double value)
+{
+ double dx, dy, x;
+ cairo_text_extents_t extents;
+ char buf[80];
+ double y;
+
+ if (fabs (value) < 0.1)
+ return;
+
+ dy = (c->height/2. - PAD) / MAX (-c->min_value, c->max_value);
+ /* the first report is always skipped, as it is used as the baseline */
+ dx = c->width / (double) (c->num_tests * c->num_reports);
+ x = dx * (c->num_reports * test + report - .5);
+
+ cairo_rectangle (c->cr,
+ floor (x), c->height / 2.,
+ floor (x + dx) - floor (x),
+ ceil (-dy*value - c->height/2.) + c->height/2.);
+ if (dx < 5) {
+ set_report_color (c, report);
+ cairo_fill (c->cr);
+ } else {
+ set_report_gradient (c, report,
+ floor (x), c->height / 2.,
+ floor (x + dx) - floor (x),
+ ceil (-dy*value - c->height/2.) + c->height/2.);
+
+ cairo_fill_preserve (c->cr);
+ cairo_save (c->cr);
+ cairo_clip_preserve (c->cr);
+ set_report_color (c, report);
+ cairo_stroke (c->cr);
+ cairo_restore (c->cr);
+ }
+
+ /* Skip the label if the difference between the two is less than 0.1% */
+ if (fabs (value) < 0.1)
+ return;
+
+ cairo_save (c->cr);
+ cairo_set_font_size (c->cr, dx - 2);
+
+ if (value < 0) {
+ sprintf (buf, "%.1f", -value/100 + 1);
+ } else {
+ sprintf (buf, "%.1f", value/100 + 1);
+ }
+ cairo_text_extents (c->cr, buf, &extents);
+
+ /* will it be clipped? */
+ y = -dy * value;
+ if (y < -c->height/2) {
+ y = -c->height/2;
+ } else if (y > c->height/2) {
+ y = c->height/2;
+ }
+
+ if (y < 0) {
+ if (y > -extents.width - 6)
+ y -= extents.width + 6;
+ } else {
+ if (y < extents.width + 6)
+ y += extents.width + 6;
+ }
+
+ cairo_translate (c->cr,
+ floor (x) + (floor (x + dx) - floor (x))/2,
+ floor (y) + c->height/2.);
+ cairo_rotate (c->cr, -M_PI/2);
+ if (y < 0) {
+ cairo_move_to (c->cr, -extents.x_bearing -extents.width - 4, -extents.y_bearing/2);
+ } else {
+ cairo_move_to (c->cr, 2, -extents.y_bearing/2);
+ }
+
+ cairo_set_source_rgb (c->cr, .95, .95, .95);
+ cairo_show_text (c->cr, buf);
+ cairo_restore (c->cr);
+}
+
+static void
add_label (struct chart *c,
int test,
const char *label)
@@ -825,6 +930,11 @@ cairo_perf_reports_compare (struct chart *chart,
num_test++;
}
+ if (chart->relative) {
+ add_label (chart, num_test, "(geometric mean)");
+ for (i = 0; i < chart->num_reports; i++)
+ add_average (chart, num_test, i, to_factor (chart->average[i]));
+ }
free (tests);
if (print) {