From c3cc2d27435278beb8c81c3d728f47665dbd3019 Mon Sep 17 00:00:00 2001 From: mattip Date: Tue, 22 Sep 2026 12:28:01 +0300 Subject: [PATCH 1/2] use pypy 3.12 for the home page graphs --- codespeed/views.py | 7 ++++++- speed_pypy/settings.py | 1 + speed_pypy/templates/embed_comparison.html | 6 ++++-- speed_pypy/templates/home.html | 10 ++++++---- 4 files changed, 17 insertions(+), 7 deletions(-) diff --git a/codespeed/views.py b/codespeed/views.py index 723f2e59..deb6d2b0 100644 --- a/codespeed/views.py +++ b/codespeed/views.py @@ -114,7 +114,9 @@ def embed_comparison(request): @require_GET def gethistoricaldata(request): - data = {'results': {}, 'benchmarks': []} + # 'labels' maps each key in tagged_revs (plus baseline and 'latest') to + # a two-line label [tag, project] for the x axis of the history chart. + data = {'results': {}, 'benchmarks': [], 'labels': {}} env = Environment.objects.all() if settings.DEF_ENVIRONMENT: env = env.get(name=settings.DEF_ENVIRONMENT) @@ -134,6 +136,7 @@ def gethistoricaldata(request): ) rev0 = rev[0] resname = '{} {}'.format(b['executable'], rev0.tag) + data['labels'][resname] = [rev0.tag, baseline_exe.project.name] baseline_results.append((resname, Result.objects.filter( executable=baseline_exe, revision=rev0, environment=env, benchmark__source='legacy'))) @@ -165,12 +168,14 @@ def gethistoricaldata(request): logger.info("no results for '%s' '%s' '%s'" % (str(_default_exe), str(rev), str(env))) continue default_results[rev.tag] = res + data['labels'][rev.tag] = [rev.tag, _default_exe.project.name] data['tagged_revs'] = [rev.tag for rev in all_taggedrevs if rev.tag in default_results] # Fetch data for latest results executable = settings.DEF_EXECUTABLES[0] def_name = executable['name'] def_project = Project.objects.get(name=executable['project']) default_exe = Executable.objects.get(name=def_name, project=def_project) + data['labels']['latest'] = ['latest', default_exe.project.name] default_branch = Branch.objects.get( name=default_exe.project.default_branch, project=default_exe.project) diff --git a/speed_pypy/settings.py b/speed_pypy/settings.py index 4d6a559f..722b9c0e 100644 --- a/speed_pypy/settings.py +++ b/speed_pypy/settings.py @@ -93,6 +93,7 @@ {'executable': 'cpython', 'revision': '3.11.15'}, ] DEF_EXECUTABLES = [ + {'name': 'pypy3.12-jit-64', 'project': 'PyPy3.12'}, {'name': 'pypy3.11-jit-64', 'project': 'PyPy3.11'}, ] DEF_ENVIRONMENT = 'benchmarker2' diff --git a/speed_pypy/templates/embed_comparison.html b/speed_pypy/templates/embed_comparison.html index 04f30028..5bd6c565 100644 --- a/speed_pypy/templates/embed_comparison.html +++ b/speed_pypy/templates/embed_comparison.html @@ -6,11 +6,13 @@ PyPy vs CPython benchmark comparison diff --git a/speed_pypy/templates/home.html b/speed_pypy/templates/home.html index 01d15c97..b6cea97b 100644 --- a/speed_pypy/templates/home.html +++ b/speed_pypy/templates/home.html @@ -31,7 +31,7 @@

Comparison

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 }}

@@ -120,9 +120,11 @@

How has PyPy performance evolved over time?

geomeans.push(1 / trunk_geomean); $('#num_of_benchs').html(num_of_benchs); - var ticks2 = [data['baseline']]; - for (var i in data['tagged_revs']) { ticks2.push(data['tagged_revs'][i]); } - ticks2.push('latest {{ default_exe.project }}'); + // Two-line labels: [tag, project]; fall back to the key itself. + var labelFor = function(key) { return (data['labels'] || {})[key] || key; }; + var ticks2 = [labelFor(data['baseline'])]; + for (var i in data['tagged_revs']) { ticks2.push(labelFor(data['tagged_revs'][i])); } + ticks2.push(labelFor('latest')); var wrap2 = document.getElementById('historical-plot'); var canvas2 = document.createElement('canvas'); From 075d6710d9965d628249b1635f51993759c3609e Mon Sep 17 00:00:00 2001 From: mattip Date: Wed, 30 Sep 2026 10:41:54 +0300 Subject: [PATCH 2/2] require source when uploading --- codespeed/results.py | 6 +++--- codespeed/tests/test_views.py | 26 +++++++++++++++++--------- tools/pypy/savecpython.py | 1 + tools/pypy/saveresults.py | 1 + tools/save_multiple_results.py | 6 ++++-- tools/save_single_result.py | 1 + 6 files changed, 27 insertions(+), 14 deletions(-) diff --git a/codespeed/results.py b/codespeed/results.py index 97e3e2ea..027f2ffd 100644 --- a/codespeed/results.py +++ b/codespeed/results.py @@ -32,6 +32,7 @@ def validate_result(item): 'benchmark', 'environment', 'result_value', + 'source', ] error = True @@ -41,7 +42,7 @@ def validate_result(item): elif key in item and item[key] == "": return 'Value for key "' + key + '" empty in request', error - if 'source' in item and item['source'] not in dict(Benchmark.S_TYPES): + if item['source'] not in dict(Benchmark.S_TYPES): return 'Invalid source "%s"' % item['source'], error try: @@ -73,9 +74,8 @@ def save_result(data, update_repo=True): p, created = Project.objects.get_or_create(name=data["project"]) branch, created = Branch.objects.get_or_create(name=data["branch"], project=p) - source = data.get("source", "legacy") b, created = Benchmark.objects.get_or_create( - name=data["benchmark"], source=source) + name=data["benchmark"], source=data["source"]) if created: if "description" in data: diff --git a/codespeed/tests/test_views.py b/codespeed/tests/test_views.py index 8f07a61f..3108d5f4 100644 --- a/codespeed/tests/test_views.py +++ b/codespeed/tests/test_views.py @@ -29,6 +29,7 @@ def setUp(self): 'benchmark': 'float', 'environment': 'Dual Core', 'result_value': 456, + 'source': 'legacy', } def test_add_correct_result(self): @@ -190,11 +191,13 @@ def test_source_set_on_new_benchmark(self): b = Benchmark.objects.get(name='newbench') self.assertEqual(b.source, 'pyperformance') - def test_source_defaults_to_legacy(self): - """A payload without a source creates a 'legacy' Benchmark""" - self.client.post(self.path, self.data) - b = Benchmark.objects.get(name='float') - self.assertEqual(b.source, 'legacy') + def test_missing_source_rejected(self): + """A payload without a source is rejected instead of defaulting""" + modified_data = copy.deepcopy(self.data) + del modified_data['source'] + response = self.client.post(self.path, modified_data) + self.assertEqual(response.status_code, 400) + self.assertFalse(Benchmark.objects.filter(name='float').exists()) def test_same_name_different_source_are_distinct(self): """The same name in a different suite is a separate Benchmark""" @@ -245,28 +248,32 @@ def setUp(self): 'executable': 'pypy-c', 'benchmark': 'Richards', 'environment': 'bigdog', - 'result_value': 456}, + 'result_value': 456, + 'source': 'legacy'}, {'commitid': '456', 'project': 'pypy', 'branch': 'default', 'executable': 'pypy-c', 'benchmark': 'Richards', 'environment': 'bigdog', - 'result_value': 457}, + 'result_value': 457, + 'source': 'legacy'}, {'commitid': '456', 'project': 'pypy', 'branch': 'default', 'executable': 'pypy-c', 'benchmark': 'Richards2', 'environment': 'bigdog', - 'result_value': 34}, + 'result_value': 34, + 'source': 'legacy'}, {'commitid': '789', 'project': 'pypy', 'branch': 'default', 'executable': 'pypy-c', 'benchmark': 'Richards', 'environment': 'bigdog', - 'result_value': 458}, + 'result_value': 458, + 'source': 'legacy'}, ] def test_get_returns_405(self): @@ -452,6 +459,7 @@ def setUp(self): 'benchmark': 'float', 'environment': 'Dual Core', 'result_value': 200, + 'source': 'legacy', } resp = self.client.post(reverse('add-result'), self.data) diff --git a/tools/pypy/savecpython.py b/tools/pypy/savecpython.py index c5200947..c15ce033 100644 --- a/tools/pypy/savecpython.py +++ b/tools/pypy/savecpython.py @@ -31,6 +31,7 @@ def save(project, revision, results, options, executable, host, testing=False): 'environment': host, 'result_value': value, 'result_date': current_date, + 'source': 'legacy', } if res_type == "ComparisonResult": data['std_dev'] = results['std_changed'] diff --git a/tools/pypy/saveresults.py b/tools/pypy/saveresults.py index 3d3eb0df..ddc000e5 100644 --- a/tools/pypy/saveresults.py +++ b/tools/pypy/saveresults.py @@ -79,6 +79,7 @@ def save(project, revision, results, executable, host, url, testing=False, 'environment': host, 'result_value': value, 'branch': branch, + 'source': 'legacy', }] if not value: print("Ignoring skipped result", data) diff --git a/tools/save_multiple_results.py b/tools/save_multiple_results.py index bc262e1a..82d340b7 100644 --- a/tools/save_multiple_results.py +++ b/tools/save_multiple_results.py @@ -18,7 +18,8 @@ "executable": "myexe O3 64bits", "benchmark": "float", "environment": "Dual Core", - "result_value": 2500.0 + "result_value": 2500.0, + "source": "legacy" }, { "commitid": "8", @@ -27,7 +28,8 @@ "executable": "myexe O3 64bits", "benchmark": "int", "environment": "Dual Core", - "result_value": 1100 + "result_value": 1100, + "source": "legacy" } ] diff --git a/tools/save_single_result.py b/tools/save_single_result.py index 830858e7..736cb77e 100644 --- a/tools/save_single_result.py +++ b/tools/save_single_result.py @@ -20,6 +20,7 @@ 'benchmark': 'float', 'environment': "Dual Core", 'result_value': 4000, + 'source': 'legacy', # 'legacy' or 'pyperformance' } # Optional fields