From b8ce891853e8e7ae99306fe34f373fceeb014085 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Thu, 28 May 2026 12:10:24 +0200 Subject: [PATCH 1/2] Make benchmark script easier to use, and fix wrong case The "long escape" bench case is the same as "long plain", fix it to actually be a long escape. Also add a "long prefix" to match the "long suffix", and bench prefix galloping modes (if any). The benchmark script requires pyperf, which is not in any of markupsafe's dependency groups, making it more complicated to run than necessary. By using a PEP 723 dependencies spec, `uv run bench.py` (or other PEP 723 runners) should work out of the box. Because the script just prints the results to stdout it's annoying to compare results between implementations, especially when getting stability warnings. By storing the benchmarks into results files, then using `compare_to` to compare them, we get the same data (kinda, it doesn't print the jitter in table form) which makes things much easier to compare. If we want to surface benchmark stability back, we can run `pyperf check` before `compare_to`. This requires touching up the naming a bit so `compare_to` can line up the benches for comparison, but that does not seem detrimental. --- bench.py | 84 ++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 58 insertions(+), 26 deletions(-) mode change 100644 => 100755 bench.py diff --git a/bench.py b/bench.py old mode 100644 new mode 100755 index 59617aa8..c47ba574 --- a/bench.py +++ b/bench.py @@ -1,30 +1,62 @@ +#!/usr/bin/env python3 +# /// scripts +# dependencies = [ +# ".", +# "pyperf", +# ] +# /// +import os +import pathlib import subprocess import sys +import tempfile -for name, s in ( - ("short escape", '"Hello, World!"'), - ("long escape", '"Hello, World!" * 1000'), - ("short plain", '"Hello, World!"'), - ("long plain", '"Hello, World!" * 1000'), - ("long suffix", '"Hello, World!" + "x" * 100_000'), -): + +with tempfile.TemporaryDirectory() as d: + outfiles = [] for mod in "native", "speedups": - subprocess.run( - [ - sys.executable, - "-m", - "pyperf", - "timeit", - "--name", - f"{name} {mod}", - "-s", - ( - "import markupsafe\n" - f"from markupsafe._{mod} import _escape_inner\n" - "markupsafe._escape_inner = _escape_inner\n" - "from markupsafe import escape\n" - f"s = {s}" - ), - "escape(s)", - ] - ) + print(mod, end="", flush=True) + outname = f"{d}/{mod}.json" + outfiles.append(outname) + for name, s in ( + ("short escape", '"Hello, World!"'), + ("long escape", '"Hello, World!" * 1000'), + ("short plain", '"Hello, World!"'), + ("long plain", '"Hello, World!" * 1000'), + ("long prefix", '"Hello, World!" * 1000 + "Hello, World!"'), + ("long suffix", '"Hello, World!" + "x" * 100_000'), + ): + subprocess.run( + [ + sys.executable, + "-m", + "pyperf", + "timeit", + "--quiet", + "--name", + name, + "--append", + outname, + "-s", + ( + "import markupsafe\n" + f"from markupsafe._{mod} import _escape_inner\n" + "markupsafe._escape_inner = _escape_inner\n" + "from markupsafe import escape\n" + f"s = {s}" + ), + "escape(s)", + ], + stdout=subprocess.DEVNULL, + ) + print('.', end='', flush=True) + print() + + subprocess.run([ + sys.executable, + '-m', + 'pyperf', + 'compare_to', + '--table', + *outfiles, + ]) From 351530852a22340f7f73db9da54813084f193200 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci-lite[bot]" <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Date: Thu, 28 May 2026 10:47:10 +0000 Subject: [PATCH 2/2] [pre-commit.ci lite] apply automatic fixes --- bench.py | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/bench.py b/bench.py index c47ba574..7797ebc9 100755 --- a/bench.py +++ b/bench.py @@ -5,13 +5,10 @@ # "pyperf", # ] # /// -import os -import pathlib import subprocess import sys import tempfile - with tempfile.TemporaryDirectory() as d: outfiles = [] for mod in "native", "speedups": @@ -23,7 +20,10 @@ ("long escape", '"Hello, World!" * 1000'), ("short plain", '"Hello, World!"'), ("long plain", '"Hello, World!" * 1000'), - ("long prefix", '"Hello, World!" * 1000 + "Hello, World!"'), + ( + "long prefix", + '"Hello, World!" * 1000 + "Hello, World!"', + ), ("long suffix", '"Hello, World!" + "x" * 100_000'), ): subprocess.run( @@ -49,14 +49,16 @@ ], stdout=subprocess.DEVNULL, ) - print('.', end='', flush=True) + print(".", end="", flush=True) print() - subprocess.run([ - sys.executable, - '-m', - 'pyperf', - 'compare_to', - '--table', - *outfiles, - ]) + subprocess.run( + [ + sys.executable, + "-m", + "pyperf", + "compare_to", + "--table", + *outfiles, + ] + )