show os-specific perf data (bug 641557)

This commit is contained in:
Jeff Balogh 2011-03-30 19:18:03 -07:00
Родитель 3f60194b43
Коммит c37e14202c
8 изменённых файлов: 321 добавлений и 220 удалений

Просмотреть файл

@ -24,13 +24,19 @@ class PerformanceAppVersions(amo.models.ModelBase):
class PerformanceOSVersion(amo.models.ModelBase):
os = models.CharField(max_length=255)
version = models.CharField(max_length=255)
name = models.CharField(max_length=255)
class Meta:
db_table = 'perf_osversions'
def __unicode__(self):
return self.name or '%s %s' % (self.os, self.version)
class Performance(amo.models.ModelBase):
"""Add-on performance numbers. A bit denormalized."""
# Cache storage for all platform perf numbers.
ALL_PLATFORMS = 'perf:platforms'
TEST_CHOICES = [('ts', 'Startup Time')]

Просмотреть файл

@ -1,8 +1,11 @@
import json
import logging
import redisutils
from celeryutils import task
from addons.models import Addon
from .models import Performance
log = logging.getLogger('z.perf.task')
@ -11,13 +14,23 @@ log = logging.getLogger('z.perf.task')
def update_perf(baseline, perf, **kw):
log.info('[%s@%s] Updating perf' %
(len(perf), update_perf.rate_limit))
all_deltas = {}
for addon, rows in perf:
if addon is None:
continue
deltas = [(avg - baseline[os]) / float(baseline[os])
for _, os, avg in rows]
if any(d < 0 for d in deltas):
deltas = dict((os, (avg - baseline[os]) / float(baseline[os]) * 100)
for _, os, avg in rows)
if any(d < 0 for d in deltas.values()):
slowness = None
all_deltas[addon] = None
else:
slowness = sum(deltas) / len(deltas) * 100
slowness = int(sum(deltas.values()) / len(deltas))
d = dict((k, int(v)) for k, v in deltas.items())
# Include the average slowness as key 0.
d[0] = slowness
all_deltas[addon] = json.dumps(d, separators=(',', ':'))
Addon.objects.filter(pk=addon).update(ts_slowness=slowness)
# Add all the calculated values to redis so we can show per-platform perf.
redis = redisutils.connections['master']
redis.hmset(Performance.ALL_PLATFORMS, all_deltas)

Просмотреть файл

@ -8,6 +8,10 @@
{% block bodyclass %}inverse{% endblock %}
{% block extrahead %}
<link rel="stylesheet" href="{{ MEDIA_URL }}css/zamboni/perf.css">
{% endblock %}
{% block content %}
<header>
@ -30,8 +34,18 @@
The following add-ons have the most impact on how long it takes {{ app }}
to start up.
{% endtrans %}</p>
{% if show_os %}
<p id="show">
{# L10n: Show All, Windows, Mac, Linux. The other names are inserted after the colon. #}
{{ _('Show:') }}
<span>
{# No spaces or all is ruined! #}
<a href="#"><b> {{ _('All') }}</b></a>{% for p in platforms|sort %}, <a href="#">{{ p }}</a>{% endfor %}
</span>
</p>
{% endif %}
<div id="perf-results">
<div id="perf-results" data-platforms="{{ platforms|json }}">
<div id="perf-results-inner">
<table>
<thead>
@ -46,8 +60,10 @@
</thead>
<tbody>
{% for addon in addons %}
<tr id="addon-{{ loop.index }}" data-rank="{{ loop.index }}"
{% if loop.index > 10 %}class="perf-hidden perf-small"{% endif %}>
<tr class="addon-row"
{% if os_perf[addon.id] %}
data-platforms="{{ os_perf[addon.id] }}"
{% endif %}>
<td class="rank">#<b>{{ loop.index }}</b></td>
<td class="addon">
<div>
@ -78,7 +94,7 @@
</tbody>
</table>
{% if addons|length > 10 %}
<p id="perf-more"><a href="#addon-11">{{ _('Show more add-ons') }}</a></p>
<p id="perf-more"><a href="#">{{ _('Show more add-ons') }}</a></p>
{% endif %}
</div>
</div>

Просмотреть файл

@ -4,10 +4,11 @@ from django.shortcuts import get_list_or_404
from django.views.decorators.cache import cache_control
import jingo
import redisutils
from addons.models import Addon
from .models import Performance
from .models import Performance, PerformanceOSVersion
@cache_control(max_age=60 * 60 * 24) # Cache for a day.
@ -15,5 +16,11 @@ def index(request):
addons = (Addon.objects.listed(request.APP)
.filter(ts_slowness__isnull=False).order_by('-ts_slowness'))
addons = get_list_or_404(addons[:50])
ids = [a.id for a in addons]
redis = redisutils.connections['master']
os_perf = dict(zip(ids, redis.hmget(Performance.ALL_PLATFORMS, ids)))
platforms = dict((unicode(p), p.id)
for p in PerformanceOSVersion.uncached.all())
return jingo.render(request, 'perf/index.html',
dict(addons=addons))
dict(addons=addons, os_perf=os_perf, platforms=platforms,
show_os=any(os_perf.values())))

206
media/css/zamboni/perf.css Normal file
Просмотреть файл

@ -0,0 +1,206 @@
/** Performance page. **/
#perf-results {
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
border: 1px solid #e0effd;
padding: 1em;
}
#perf-results table {
border-bottom: 1px dotted #add0dc;
margin-bottom: 0;
width: 100%;
}
/* Hide children over 10 until show-more is clicked. */
#perf-results:not(.show-more) .addon-row:nth-child(n+10) {
display: none;
}
#perf-results th {
font-size: 11px;
vertical-align: top;
padding: 0 20px 8px 0;
}
#perf-results th.rank {
width: 32px;
}
.html-rtl #perf-results th.rank {
padding-right: 0;
text-align: right;
}
#perf-results th.impact {
padding-right: 0;
width: 300px;
}
#perf-results th.impact .percentage {
color: #999;
font-weight: normal;
}
#perf-results td {
border-top: 1px dotted #add0dc;
padding: 8px 0;
vertical-align: middle;
}
#perf-results td.rank {
vertical-align: top;
}
#perf-results td.rank b,
#perf-results td.impact b,
#perf-results td.addon .addon-title > a {
font-size: 1.4em;
}
#perf-results td.rank b {
font-weight: normal;
vertical-align: top;
}
#perf-results td.addon div {
position: relative;
}
#perf-results td.addon img.icon,
#perf-results td.addon .addon-title,
#perf-results td.addon .author {
display: block;
}
#perf-results td.addon img.icon {
position: absolute;
top: 0;
left: 0;
}
.html-rtl #perf-results td.addon img.icon {
right: 0;
}
#perf-results th.addon,
#perf-results td.addon .addon-title {
padding-left: 50px;
}
.html-rtl #perf-results th.addon,
.html-rtl #perf-results td.addon .addon-title {
padding-left: 0;
padding-right: 50px;
}
#perf-results td.addon .addon-title > a {
font-weight: bold;
}
#perf-results td.impact {
color: #777;
line-height: 1.3em;
}
#perf-results .addon-row:nth-child(n+10) td.rank b,
#perf-results .addon-row:nth-child(n+10) td.impact b,
#perf-results .addon-row:nth-child(n+10) td.addon .addon-title > a {
font-size: 1.0em;
}
#perf-results .addon-row:nth-child(n+10) td.addon img.icon,
#perf-results .addon-row:nth-child(n+10) td.addon .author,
#perf-results .addon-row:nth-child(n+10) td.impact .slower span {
display: none;
}
#perf-results .addon-row:nth-child(n+10) td.addon img.icon {
display: none;
}
#perf-results .impact .slower,
#perf-results .impact .percentage {
display: table-cell;
}
#perf-results .impact .slower {
text-align: right;
width: 100px;
}
.html-rtl #perf-results .impact .slower {
text-align: left;
}
#perf-results .impact .percentage {
width: 70%;
}
#perf-results .impact .slower {
padding-right: 10px;
}
.html-rtl #perf-results .impact .slower {
padding: 0 0 0 10px;
}
#perf-results td.impact .slower {
border-right: 1px solid #f77;
}
.html-rtl #perf-results td.impact .slower {
border-right-width: 0;
border-left: 1px solid #f77;
}
#perf-results td.impact .percentage {
vertical-align: middle;
}
#perf-results td.impact b {
color: #444;
display: block;
}
#perf-results .bar {
background-color: #f77;
height: 15px;
-moz-transition: .5s width;
}
#perf-results .addon-row:nth-child(n+10) .bar {
height: 10px;
}
#perf-results p#perf-more {
font-size: 0.9em;
margin: 1em 0 0 52px;
}
#perf-results p#perf-more a {
background: url(../../img/icons/arrows.gif) 100% -73px no-repeat;
padding-right: 15px;
}
.html-rtl #perf-results p#perf-more a {
background-position: 0 -73px;
padding: 0 0 0 15px;
}
#perf-results p#perf-more a:hover,
#perf-results p#perf-more a:focus,
#perf-results p#perf-more a:active {
background-position: 100% -113px;
}
.html-rtl #perf-results p#perf-more a:hover,
.html-rtl #perf-results p#perf-more a:focus,
.html-rtl #perf-results p#perf-more a:active {
background-position: 0 -113px;
}

Просмотреть файл

@ -2114,204 +2114,6 @@ form .error .note.error {
}
/** Performance page. **/
#perf-results {
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
border: 1px solid #e0effd;
padding: 1em;
}
#perf-results table {
border-bottom: 1px dotted #add0dc;
margin-bottom: 0;
width: 100%;
}
#perf-results .perf-hidden {
display: none;
}
#perf-results th {
font-size: 11px;
vertical-align: top;
padding: 0 20px 8px 0;
}
#perf-results th.rank {
width: 32px;
}
.html-rtl #perf-results th.rank {
padding-right: 0;
text-align: right;
}
#perf-results th.impact {
padding-right: 0;
width: 300px;
}
#perf-results th.impact .percentage {
color: #999;
font-weight: normal;
}
#perf-results td {
border-top: 1px dotted #add0dc;
padding: 8px 0;
vertical-align: middle;
}
#perf-results td.rank {
vertical-align: top;
}
#perf-results td.rank b,
#perf-results td.impact b,
#perf-results td.addon .addon-title > a {
font-size: 1.4em;
}
#perf-results .perf-small td.rank b,
#perf-results .perf-small td.impact b,
#perf-results .perf-small td.addon .addon-title > a {
font-size: 1.0em;
}
#perf-results .perf-small td.addon img.icon,
#perf-results .perf-small td.addon .author,
#perf-results .perf-small td.impact .slower span {
display: none;
}
#perf-results td.rank b {
font-weight: normal;
vertical-align: top;
}
#perf-results td.addon div {
position: relative;
}
#perf-results td.addon img.icon,
#perf-results td.addon .addon-title,
#perf-results td.addon .author {
display: block;
}
#perf-results td.addon img.icon {
position: absolute;
top: 0;
left: 0;
}
.html-rtl #perf-results td.addon img.icon {
right: 0;
}
#perf-results th.addon,
#perf-results td.addon .addon-title {
padding-left: 50px;
}
.html-rtl #perf-results th.addon,
.html-rtl #perf-results td.addon .addon-title {
padding-left: 0;
padding-right: 50px;
}
#perf-results td.addon .addon-title > a {
font-weight: bold;
}
#perf-results td.impact {
color: #777;
line-height: 1.3em;
}
#perf-results .impact .slower,
#perf-results .impact .percentage {
display: table-cell;
}
#perf-results .impact .slower {
text-align: right;
width: 100px;
}
.html-rtl #perf-results .impact .slower {
text-align: left;
}
#perf-results .impact .percentage {
width: 70%;
}
#perf-results .impact .slower {
padding-right: 10px;
}
.html-rtl #perf-results .impact .slower {
padding: 0 0 0 10px;
}
#perf-results td.impact .slower {
border-right: 1px solid #f77;
}
.html-rtl #perf-results td.impact .slower {
border-right-width: 0;
border-left: 1px solid #f77;
}
#perf-results td.impact .percentage {
vertical-align: middle;
}
#perf-results td.impact b {
color: #444;
display: block;
}
#perf-results .bar {
background-color: #f77;
height: 15px;
}
#perf-results .perf-small .bar {
height: 10px;
}
#perf-results p#perf-more {
font-size: 0.9em;
margin: 1em 0 0 52px;
}
#perf-results p#perf-more a {
background: url(../../img/icons/arrows.gif) 100% -73px no-repeat;
padding-right: 15px;
}
.html-rtl #perf-results p#perf-more a {
background-position: 0 -73px;
padding: 0 0 0 15px;
}
#perf-results p#perf-more a:hover,
#perf-results p#perf-more a:focus,
#perf-results p#perf-more a:active {
background-position: 100% -113px;
}
.html-rtl #perf-results p#perf-more a:hover,
.html-rtl #perf-results p#perf-more a:focus,
.html-rtl #perf-results p#perf-more a:active {
background-position: 0 -113px;
}
/** =Personas Details page *********/
.persona-img {
height: 100px;

Просмотреть файл

@ -1,15 +1,60 @@
$(document).ready(function() {
$("#perf-more a").click(function(e) {
var loc = $(this).attr("href");
$("#perf-results tr.perf-hidden:lt(40)").removeClass("perf-hidden");
var $next = $("#perf-results tr.perf-hidden:eq(0)");
if ($next.length) {
$(this).attr("href", "#addon-" + $next.attr("data-rank"));
} else {
$("#perf-more").remove();
$("#perf-results table").css("border-bottom-width", 0);
$("#perf-results tr:last-child").find("td, .impact div")
.css("padding-bottom", 0);
}
"use strict";
var $perfResults = $('#perf-results'),
platforms = JSON.parse($perfResults.attr('data-platforms')),
results = [];
// We only show 10 at the beginning and toggle the rest here.
$('#perf-more a').click(function(e) {
e.preventDefault();
$('#perf-more').remove();
$perfResults.addClass('show-more');
});
// Add All to the platforms map.
platforms[gettext('All')] = 0;
// Gather all the os-specific data.
$perfResults.find('tbody tr').each(function(i, e) {
var p = $(this).attr('data-platforms')
results.push(p ? JSON.parse(p) : {});
});
if ($('#show').length == 0) {
return;
}
// Switch to js strings so we have consistent gettext.
switchNumbers(gettext('All'));
$('#show').delegate('a', 'click', function(e) {
e.preventDefault();
switchNumbers($.trim($(this).text()));
});
// Change numbers and bar graphs to the selected platform data.
function switchNumbers(selected) {
var platform = platforms[selected],
numbers = $.map(results, function(e) { return e[platform] || 0; }),
worst = Math.max.apply(null, numbers);
$perfResults.find('tbody tr').each(function(i, e) {
var $this = $(this),
num = results[i][platform] || 0;
$this.find('.slower b').text(num === 0 ? gettext('N/A') : num + '%');
$this.find('.bar').css('width', num / worst * 100 + '%');
});
showPlatforms(selected);
}
// Redisplay the list of names to select the current platform.
function showPlatforms(selected) {
var _names = _.keys(platforms);
_names.sort()
var names = $.map(_names, function(e) {
var name = e == selected ? '<b>' + e + '</b>' : e;
return format('<a href="#">{0}</a>', name);
});
$('#show span').html(names.join(', '));
}
});

Просмотреть файл

@ -0,0 +1,6 @@
ALTER TABLE perf_osversions ADD COLUMN name varchar(255);
UPDATE perf_osversions SET name='Mac OS X 10.5.8' WHERE id=1;
UPDATE perf_osversions SET name='Fedora 12' WHERE id=2;
UPDATE perf_osversions SET name='Windows XP' WHERE id=3;
UPDATE perf_osversions SET name='Windows 7' WHERE id=4