Skip to content

Commit b2dab52

Browse files
committed
Implement historical graphs on home page
- Based on PyPy's branch
1 parent 1480a47 commit b2dab52

File tree

4 files changed

+203
-23
lines changed

4 files changed

+203
-23
lines changed

codespeed/static/css/main.css

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,28 @@ a.checkall, a.uncheckall { font-size: small; color: #AAAAAA; }
239239

240240
p.errormessage { line-height: 10em; margin-bottom: 10em; }
241241

242+
/* Home page */
243+
div#historical {
244+
width: 800px;
245+
margin: 0 auto;
246+
padding-bottom: 5em;
247+
}
248+
div#baseline-comparison-plot {
249+
width: 750px;
250+
height: 400px;
251+
margin: 0 auto;
252+
}
253+
div#historical-plot {
254+
width:600px;
255+
height:400px;
256+
margin: 0 auto;
257+
}
258+
div#historical p { padding-left: 0; }
259+
div#historical p.plot-caption {
260+
height: 1em;
261+
font-size: smaller;
262+
}
263+
242264
/* Changes table layout */
243265
div#contentwrap { display: table; table-layout: fixed; width: 100%; }
244266
div#contentwrap div { display: table-cell; }

codespeed/static/js/jqplot/jqplot.pointLabels.min.js

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

codespeed/templates/codespeed/timeline.html

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
{% extends "codespeed/base_site.html" %}
2-
32
{% load static %}
43

54
{% block title %}{{ block.super }}: Timeline{% endblock %}

sample_project/templates/home.html

Lines changed: 180 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,59 @@
11
{% extends "codespeed/base_site.html" %}
2+
{% load static %}
23

34
{% block navigation %}
45
{% endblock navigation %}
56

67
{% block body %}
78
<div id="presentation" class="clearfix">
8-
<a href="{% url "changes" %}">
9-
<div id="changes" class="menubox">
10-
<h2>Changes</h2>
11-
<p>Track performance changes in the latest revisions</p>
12-
</div>
13-
</a>
14-
<a href="{% url "timeline" %}">
15-
<div id="timeline" class="menubox">
16-
<h2>Timeline</h2>
17-
<p>Analyze performance over time</p>
18-
</div>
19-
</a>
20-
<a href="{% url "comparison" %}">
21-
<div id="comparison" class="menubox">
22-
<h2>Comparison</h2>
23-
<p>Compare different executables and revisions</p>
24-
</div>
25-
</a>
26-
<br />
27-
<div id="reports"></div>
9+
<a href="{% url "changes" %}">
10+
<div id="changes" class="menubox">
11+
<h2>Changes</h2>
12+
<p>Track performance changes in the latest revisions</p>
13+
</div>
14+
</a>
15+
<a href="{% url "timeline" %}">
16+
<div id="timeline" class="menubox">
17+
<h2>Timeline</h2>
18+
<p>Analyze performance over time</p>
19+
</div>
20+
</a>
21+
<a href="{% url "comparison" %}">
22+
<div id="comparison" class="menubox">
23+
<h2>Comparison</h2>
24+
<p>Compare different executables and revisions</p>
25+
</div>
26+
</a>
27+
<br />
28+
<div id="reports"></div>
29+
{% if show_historical %}
30+
<div id="historical">
31+
<h3>How fast is {{ default_exe.project }}?</h3>
32+
<div id="baseline-comparison-plot"></div>
33+
<p class="plot-caption">Plot 1: The above plot represents {{ default_exe.project }} ({{ default_exe }}) benchmark times normalized to {{ baseline }}. Smaller is better.</p>
34+
<p>It depends greatly on the type of task being performed. The geometric average of all benchmarks is <span id="geomean"></span> or <strong id="geofaster"></strong> times <em>faster</em> than {{ baseline }}</p>
35+
36+
<h3>How has {{ default_exe.project }} performance evolved over time?</h3>
37+
<div id="historical-plot"></div>
38+
<p class="plot-caption">Plot 2: Speedup compared to {{ baseline }}, using the inverse of the geometric average of normalized times, out of <span id="num_of_benchs"></span> benchmarks (see <a href="http://dl.acm.org/citation.cfm?id=5673" title="How not to lie with statistics: the correct way to summarize benchmark results">paper</a> on why the geometric mean is better for normalized results).</p>
39+
</div>
40+
{% endif %}
2841
</div>
2942
{% endblock body %}
3043

3144
{% block extra_script %}
3245
{{ block.super }}
46+
{% if show_historical %}
47+
<link rel="stylesheet" type="text/css" href="{% static 'js/jqplot/jquery.jqplot.min.css' %}" />
48+
<script type="text/javascript" src="{% static 'js/jqplot/jquery.jqplot.min.js' %}"></script>
49+
<script type="text/javascript" src="{% static 'js/jqplot/jqplot.barRenderer.min.js' %}"></script>
50+
<script type="text/javascript" src="{% static 'js/jqplot/jqplot.canvasAxisTickRenderer.min.js' %}"></script>
51+
<script type="text/javascript" src="{% static 'js/jqplot/jqplot.categoryAxisRenderer.min.js' %}"></script>
52+
<script type="text/javascript" src="{% static 'js/jqplot/jqplot.canvasAxisLabelRenderer.min.js' %}"></script>
53+
<script type="text/javascript" src="{% static 'js/jqplot/jqplot.pointLabels.min.js' %}"></script>
54+
<script type="text/javascript" src="{% static 'js/jqplot/jqplot.canvasTextRenderer.min.js' %}"></script>
55+
{% endif %}
56+
3357
<script type="text/javascript">
3458
function updateReportTables() {
3559
//Add permalink events to table rows
@@ -46,9 +70,143 @@ <h2>Comparison</h2>
4670
});
4771
}
4872

73+
function numOrd(a, b){ return (a-b); }
74+
75+
function renderplot(data) {
76+
var plotoptions = {};
77+
var plotdata = [new Array(), new Array()];
78+
var labels = new Array();
79+
var benchmarks = new Array();
80+
if (data === null || data.length === 0) {
81+
$("#baseline-comparison-plot").html(getLoadText('Error retrieving data', 0));
82+
return 1;
83+
}
84+
var trunk_geomean = 1;
85+
var tagged_data = new Array();
86+
for (i in data['tagged_revs']) {
87+
tagged_data[i] = new Array();
88+
}
89+
for (var bench in data['benchmarks']) {
90+
var relative_value = 0;
91+
benchname = data['benchmarks'][bench];
92+
var add_to_tagged_data = true;
93+
for (var i in data['tagged_revs']) {
94+
var rev = data['tagged_revs'][i];
95+
if (data['results'][benchname][rev] === 0) {
96+
add_to_tagged_data = false;
97+
}
98+
if (add_to_tagged_data === false) { break; }
99+
relative_value = data['results'][benchname][rev]/data['results'][benchname][data['baseline']];
100+
tagged_data[i].push(relative_value)
101+
}
102+
// Only add benchmark if there are no 0 values
103+
if (add_to_tagged_data === false) { continue; }
104+
// First add benchmark
105+
benchmarks.push(benchname);
106+
// Add latest results and baseline
107+
relative_value = data['results'][benchname]['latest']/data['results'][benchname][data['baseline']];
108+
plotdata[0].push(relative_value);
109+
plotdata[1].push(1.0);
110+
labels.push(relative_value.toFixed(2));
111+
trunk_geomean *= relative_value;
112+
}
113+
trunk_geomean = Math.pow(trunk_geomean, 1/plotdata[0].length);
114+
var geofaster = 1/trunk_geomean;
115+
$('#geomean').html(trunk_geomean.toFixed(2));
116+
$('#geofaster').html(geofaster.toFixed(1));
117+
// Render first plot
118+
plotoptions1 = {
119+
legend:{show:true},
120+
seriesDefaults: {
121+
showMarker: false,
122+
rendererOptions:{barPadding: 2, barMargin:5}
123+
},
124+
axesDefaults: {
125+
tickRenderer: $.jqplot.CanvasAxisTickRenderer
126+
},
127+
series:[
128+
{
129+
label: 'latest',
130+
renderer:$.jqplot.BarRenderer,
131+
pointLabels:{labels: labels}
132+
},
133+
{
134+
label: data['baseline'],
135+
pointLabels:{show: false}
136+
}
137+
],
138+
axes: {
139+
xaxis: {
140+
renderer: $.jqplot.CategoryAxisRenderer,
141+
ticks: benchmarks,
142+
tickOptions: {angle: -40}
143+
},
144+
yaxis:{
145+
ticks: [0, 0.25, 0.5, 0.75, 1, 1.25],
146+
tickOptions:{formatString: '%.2f'}
147+
}
148+
}
149+
};
150+
plot1 = $.jqplot("baseline-comparison-plot", plotdata, plotoptions1);
151+
152+
// Prepare and render second plot
153+
var geomeans = [1.0];
154+
var num_of_benchs = 0;
155+
for (var i in data['tagged_revs']) {
156+
num_of_benchs = tagged_data[i].length;
157+
var tempgeo = 1;
158+
for (var j in tagged_data[i]) {
159+
tempgeo *= tagged_data[i][j];
160+
}
161+
tempgeo = Math.pow(tempgeo, 1/tagged_data[i].length);
162+
tempgeo = 1/tempgeo;
163+
geomeans.push(tempgeo);
164+
}
165+
geomeans.push(1/trunk_geomean);
166+
var ticks = [data['baseline']];
167+
for (var i in data['tagged_revs']) {
168+
ticks.push(data['tagged_revs'][i]);
169+
}
170+
ticks.push('latest');
171+
var geolabels = new Array();
172+
for (var i in geomeans) {
173+
geolabels.push(geomeans[i].toFixed(2) + "x");
174+
}
175+
$('#num_of_benchs').html(num_of_benchs)
176+
177+
plotoptions2 = {
178+
seriesDefaults: {
179+
renderer:$.jqplot.BarRenderer,
180+
showMarker: false
181+
},
182+
series:[
183+
{
184+
pointLabels:{labels:geolabels}
185+
}
186+
],
187+
axes: {
188+
xaxis: {
189+
renderer: $.jqplot.CategoryAxisRenderer,
190+
ticks: ticks
191+
},
192+
yaxis:{
193+
min: 0,
194+
tickOptions:{formatString:'%.2f'}
195+
}
196+
}
197+
};
198+
plot2 = $.jqplot("historical-plot", [geomeans], plotoptions2);
199+
}
200+
49201
$(function() {
50-
$("#reports").html(getLoadText("Loading...", 0))
51-
.load("{% url "reports" %}", function(responseText) { updateReportTables(); });
202+
{% if show_reports %}
203+
$("#reports").html(getLoadText("Loading...", 0))
204+
.load("{% url "reports" %}", function(responseText) { updateReportTables(); });
205+
{% endif %}
206+
207+
{% if show_historical %}
208+
$.getJSON("{% url "gethistoricaldata" %}", renderplot);
209+
{% endif %}
52210
});
53211
</script>
54212
{% endblock %}

0 commit comments

Comments
 (0)