Skip to content

gh-126703: add freelist for ints with small number of digits #129638

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

eendebakpt
Copy link
Contributor

@eendebakpt eendebakpt commented Feb 4, 2025

Benchmark:

bench_gcd: Mean +- std dev: [main] 194 us +- 5 us -> [pr2] 184 us +- 6 us: 1.05x faster
bench_uuid8: Mean +- std dev: [main] 1.69 us +- 0.04 us -> [pr2] 1.64 us +- 0.02 us: 1.03x faster
bench_id: Mean +- std dev: [main] 48.2 us +- 1.4 us -> [pr2] 41.6 us +- 1.0 us: 1.16x faster

Benchmark hidden because not significant (1): bench_int

Geometric mean: 1.06x faster

The bench_int is not affected since the compact ints already have a freelist in current main. The bench_id is a microbenchmark that does minimal amount of work. The bench_gcd and bench_uuid8 are benchmarks that are representative for real code.

Statistics for the number of allocations saved can be found in the corresponding issue.

Benchmark script:
# Quick benchmark for cpython freelists for int

from uuid import uuid8
import pyperf


def collatz(a):
    while a > 1:
        if a % 2 == 0:
            a = a // 2
        else:
            a = 3 * a + 1

def bench_int(loops):
    range_it = range(loops)
    tpl = tuple(range(200, 300))

    t0 = pyperf.perf_counter()
    for ii in range_it:
        for jj in tpl:
            collatz(jj)
    return pyperf.perf_counter() - t0

def gcd(x, y):
    while y != 0:
        (x, y) = (y, x % y)
    return x

def bench_gcd(loops):
    range_it = range(loops)
    tpl = tuple(range(100))

    t0 = pyperf.perf_counter()
    for ii in range_it:
        for a in tpl:
            gcd( (2<<120) + 1231231232131, 2<<30+ a)
    return pyperf.perf_counter() - t0

def bench_uuid8(loops):
    range_it = iter(range(loops))

    t0 = pyperf.perf_counter()
    for ii in range_it:
        _ = uuid8()
    return pyperf.perf_counter() - t0

def bench_id(loops):
    range_it = iter(range(loops))

    t0 = pyperf.perf_counter()
    for ii in range_it:
        for jj in range(1000):
            _ = id(jj)
    return pyperf.perf_counter() - t0


if __name__ == "__main__":
    runner = pyperf.Runner()
    runner.bench_time_func("bench_int", bench_int)
    runner.bench_time_func("bench_gcd", bench_gcd)
    runner.bench_time_func("bench_uuid8", bench_uuid8)
    runner.bench_time_func("bench_id", bench_id)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant