perf/chart: Show the geometric average as an extra column

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
Chris Wilson 2012-12-29 18:30:48 +00:00
parent 71028865fa
commit fbd4864995

View file

@ -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);
@ -450,6 +470,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,
@ -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) {