From f661d20df61d0f06558f3ab2db6a07e1363ce26c Mon Sep 17 00:00:00 2001 From: Stan Ulbrych Date: Mon, 22 Jun 2026 17:10:41 +0100 Subject: [PATCH 1/2] Generate a page with baseline comparison for pypy.org --- codespeed/urls.py | 1 + codespeed/views.py | 19 +++++ speed_pypy/templates/embed_comparison.html | 88 ++++++++++++++++++++++ speed_pypy/templates/home.html | 1 + 4 files changed, 109 insertions(+) create mode 100644 speed_pypy/templates/embed_comparison.html diff --git a/codespeed/urls.py b/codespeed/urls.py index cd83233e..89b6881f 100644 --- a/codespeed/urls.py +++ b/codespeed/urls.py @@ -14,6 +14,7 @@ ] urlpatterns += [ + re_path(r'^embed/comparison/$', views.embed_comparison, name='embed-comparison'), re_path(r'^historical/json/$', views.gethistoricaldata, name='gethistoricaldata'), re_path(r'^reports/$', views.reports, name='reports'), re_path(r'^changes/$', views.changes, name='changes'), diff --git a/codespeed/views.py b/codespeed/views.py index 878b7a24..5b324834 100644 --- a/codespeed/views.py +++ b/codespeed/views.py @@ -16,6 +16,7 @@ from django.shortcuts import get_object_or_404, render from django.views.decorators.http import require_GET, require_POST from django.views.decorators.csrf import csrf_exempt +from django.views.decorators.clickjacking import xframe_options_exempt from django.views.generic.base import TemplateView from .auth import basic_auth_required @@ -93,6 +94,24 @@ def get_context_data(self, **kwargs): return context +@require_GET +@xframe_options_exempt +def embed_comparison(request): + """Frame-exempt page rendering only the baseline-comparison + for embedding on pypy.org""" + context = {} + try: + context['baseline'] = Executable.objects.get( + name=settings.DEF_BASELINES[0]['executable']) + def_name = settings.DEF_EXECUTABLES[0]['name'] + def_project = Project.objects.get(name=settings.DEF_EXECUTABLES[0]['project']) + context['default_exe'] = Executable.objects.get( + name=def_name, project=def_project) + except Exception as e: + logger.error('embed_comparison: %s', e) + return render(request, 'embed_comparison.html', context) + + @require_GET def gethistoricaldata(request): data = {'results': {}, 'benchmarks': []} diff --git a/speed_pypy/templates/embed_comparison.html b/speed_pypy/templates/embed_comparison.html new file mode 100644 index 00000000..04f30028 --- /dev/null +++ b/speed_pypy/templates/embed_comparison.html @@ -0,0 +1,88 @@ +{% load static %} + + + + + + PyPy vs CPython benchmark comparison + + + +
+ + + + + + diff --git a/speed_pypy/templates/home.html b/speed_pypy/templates/home.html index 93b051d6..b487e7a2 100644 --- a/speed_pypy/templates/home.html +++ b/speed_pypy/templates/home.html @@ -102,6 +102,7 @@

How has PyPy performance evolved over time?

$('#geofaster').html((1 / trunk_geomean).toFixed(1)); // Plot 1: per-benchmark normalized comparison + // Needs to be kept in sync with the plot in embed_comparison.html var wrap1 = document.getElementById('baseline-comparison-plot'); var canvas1 = document.createElement('canvas'); wrap1.appendChild(canvas1); From 636a4e79d7d217dfc11ec2878364063116ac52b3 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych Date: Tue, 23 Jun 2026 20:59:15 +0100 Subject: [PATCH 2/2] Embed the comparison on home page to reduce duplication --- speed_pypy/templates/home.html | 44 +++++++--------------------------- 1 file changed, 9 insertions(+), 35 deletions(-) diff --git a/speed_pypy/templates/home.html b/speed_pypy/templates/home.html index b487e7a2..01d15c97 100644 --- a/speed_pypy/templates/home.html +++ b/speed_pypy/templates/home.html @@ -29,7 +29,10 @@

Comparison

{% if show_historical %}

How fast is {{ default_exe.project }}?

-
+

Plot 1: The above plot represents {{ default_exe.project }} ({{ default_exe }}) benchmark times normalized to {{ baseline }}. Smaller is better.

It depends greatly on the type of task being performed. The geometric average of all benchmarks is or times faster than {{ baseline }}

@@ -68,15 +71,15 @@

How has PyPy performance evolved over time?

function renderplot(data) { if (data === null || data.length === 0) { - $("#baseline-comparison-plot").html(getLoadText('Error retrieving data', 0)); + $("#historical-plot").html(getLoadText('Error retrieving data', 0)); return; } if (typeof data === 'string' || data instanceof String) { - $("#baseline-comparison-plot").html(getLoadText('Error retrieving data ' + data, 0)); + $("#historical-plot").html(getLoadText('Error retrieving data ' + data, 0)); return; } - var benchmarks = [], latestValues = [], baselineValues = []; + var latestValues = []; var trunk_geomean = 1; var tagged_data = []; for (var i in data['tagged_revs']) { tagged_data[i] = []; } @@ -90,10 +93,8 @@

How has PyPy performance evolved over time?

tagged_data[i].push(data['results'][benchname][rev] / data['results'][benchname][data['baseline']]); } if (!add_to_tagged_data) { continue; } - benchmarks.push(benchname); var rel = data['results'][benchname]['latest'] / data['results'][benchname][data['baseline']]; latestValues.push(rel); - baselineValues.push(1.0); if (rel > 0 && !isNaN(rel)) { trunk_geomean *= rel; } } @@ -101,35 +102,8 @@

How has PyPy performance evolved over time?

$('#geomean').html(trunk_geomean.toFixed(2)); $('#geofaster').html((1 / trunk_geomean).toFixed(1)); - // Plot 1: per-benchmark normalized comparison - // Needs to be kept in sync with the plot in embed_comparison.html - var wrap1 = document.getElementById('baseline-comparison-plot'); - var canvas1 = document.createElement('canvas'); - wrap1.appendChild(canvas1); - new Chart(canvas1, { - type: 'bar', - data: { - labels: benchmarks, - datasets: [ - {label: 'latest {{ default_exe }}', data: latestValues, backgroundColor: '#4e79a7'}, - {label: data['baseline'], data: baselineValues, type: 'line', - borderColor: '#f28e2b', backgroundColor: 'transparent', - pointRadius: 0, borderWidth: 2, fill: false} - ] - }, - options: { - animation: false, - responsive: true, - maintainAspectRatio: false, - plugins: { - tooltip: {position: 'cursor'} - }, - scales: { - x: {ticks: {maxRotation: 70, minRotation: 70, autoSkip: false, font: {size: 11}}}, - y: {min: 0, max: 2.0, ticks: {callback: function(v) { return v.toFixed(2); }}} - } - } - }); + // Plot 1 (per-benchmark normalized comparison) is rendered by the + // embed_comparison page shown in the iframe above. // Plot 2: geomean speedup over tagged revisions var geomeans = [1.0];