From 32eb0045ecac25e09b748f860f410e6e5d6db928 Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Mon, 19 Jan 2026 15:17:23 +0300 Subject: [PATCH] Enable decimal benchmarks in the suite (MANIFEST) They were not added here in #341 for no reasons. Tune bench_decimal_factorial() to support pure-Python decimal module on PyPy. See also python/cpython#155198. Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Closes #473 --- pyperformance/data-files/benchmarks/MANIFEST | 2 + .../bm_decimal_factorial/run_benchmark.py | 40 +++++++++++++++---- 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/pyperformance/data-files/benchmarks/MANIFEST b/pyperformance/data-files/benchmarks/MANIFEST index 35777453..b08fe830 100644 --- a/pyperformance/data-files/benchmarks/MANIFEST +++ b/pyperformance/data-files/benchmarks/MANIFEST @@ -39,6 +39,8 @@ chaos comprehensions crypto_pyaes dask +decimal_factorial +decimal_pi deepcopy deltablue django_template diff --git a/pyperformance/data-files/benchmarks/bm_decimal_factorial/run_benchmark.py b/pyperformance/data-files/benchmarks/bm_decimal_factorial/run_benchmark.py index dceba16b..7ddac37d 100644 --- a/pyperformance/data-files/benchmarks/bm_decimal_factorial/run_benchmark.py +++ b/pyperformance/data-files/benchmarks/bm_decimal_factorial/run_benchmark.py @@ -4,6 +4,9 @@ - 2024-06-14: Michael Droettboom copied this from Modules/_decimal/tests/bench.py in the CPython source and adapted to use pyperf. +- 2026-09-26: Sergey B Kirpichev adapted context settings and tested + values to support also pure-Python decimal module, copy + increase_int_max_str_digits() decorator. """ # Original copyright notice in CPython source: @@ -13,9 +16,13 @@ # Modified and extended by Stefan Krah. # - import decimal - +try: + import _decimal +except ImportError: + _decimal = None +import sys +from functools import wraps import pyperf @@ -31,14 +38,33 @@ def factorial(n, m): return factorial(n, (n + m) // 2) * factorial((n + m) // 2 + 1, m) +def increase_int_max_str_digits(maxdigits): + def _increase_int_max_str_digits(func, maxdigits=maxdigits): + @wraps(func) + def wrapper(*args, **kwargs): + previous_int_limit = sys.get_int_max_str_digits() + sys.set_int_max_str_digits(maxdigits) + ans = func(*args, **kwargs) + sys.set_int_max_str_digits(previous_int_limit) + return ans + return wrapper + return _increase_int_max_str_digits + + +@increase_int_max_str_digits(maxdigits=10000000) def bench_decimal_factorial(): c = decimal.getcontext() - c.prec = decimal.MAX_PREC - c.Emax = decimal.MAX_EMAX - c.Emin = decimal.MIN_EMIN + if _decimal: + c.prec = decimal.MAX_PREC + c.Emax = decimal.MAX_EMAX + c.Emin = decimal.MIN_EMIN + data = [10000, 100000] + else: + # Workaround for python/cpython#140036 (PyPy uses pure-Python Decimal's) + c.prec = 20000 # Should be enough to hold largest factorial exactly. + data = [1000, 5000] - for n in [10000, 100000]: - # C version of decimal + for n in data: _ = factorial(decimal.Decimal(n), 0)