Skip to content

Optimize frozendict lookup on Free-Threaded build #145481

@vstinner

Description

@vstinner

Frozendict lookups use locks and atomic operations for thread safety. We should be able to use a faster implementation for frozendict, avoid locks and atomic operations, since the frozendict mapping is immutable.

Stress test on frozendict lookup comparing a regular build (ref) to a free-threading build (nogil):

Benchmark ref nogil
int keys 8.36 ms 7.40 ms: 1.13x faster
str keys 231 ms 334 ms: 1.45x slower
Geometric mean (ref) 1.13x slower

Benchmark code:

Details
import pyperf
from threading import Thread
import os

frozendict_int_keys = frozendict((i, i) for i in range(10))
frozendict_str_keys = frozendict((str(i), i) for i in range(10))
LOOPS = 2 ** 13
NTHREAD = os.process_cpu_count()

def compute_int_keys():
    data = frozendict_int_keys  # use a local variable
    total = 0
    for _ in range(LOOPS):
        total += data[0]
        total += data[1]
        total += data[2]
        total += data[3]
        total += data[4]
        total += data[5]
        total += data[6]
        total += data[7]
        total += data[8]
        total += data[9]
    return total

def compute_str_keys():
    data = frozendict_str_keys  # use a local variable
    total = 0
    for _ in range(LOOPS):
        total += data['0']
        total += data['1']
        total += data['2']
        total += data['3']
        total += data['4']
        total += data['5']
        total += data['6']
        total += data['7']
        total += data['8']
        total += data['9']
    return total

def bench(target):
    threads = [Thread(target=target) for _ in range(NTHREAD)]
    for thread in threads:
        thread.start()
    for thread in threads:
        thread.join()

runner = pyperf.Runner()
runner.bench_func('int keys', bench, compute_int_keys)
runner.bench_func('str keys', bench, compute_str_keys)

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions