FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

gh-141510: Avoid critical section on frozendict copy by vstinner · Pull Request #145920 · python/cpython · GitHub

/ cpython Public

gh-141510: Avoid critical section on frozendict copy - #145920

Merged
vstinner merged 2 commits into
python:mainfrom
vstinner:optim_frozendict_copy
Mar 16, 2026
Merged

gh-141510: Avoid critical section on frozendict copy#145920
vstinner merged 2 commits into
python:mainfrom
vstinner:optim_frozendict_copy

Conversation

vstinner commented Mar 13, 2026
edited by bedevere-app Bot
Loading

Copy link
Copy Markdown
Member

Copy link
Copy Markdown
Member Author

cc @corona10

clin1234 left a comment
edited
Loading

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

So far, LGTM, though I am curious about concurrency safety in eliding a critical section when copying a frozendict, especially with a free-threaded interpreter

Copy link
Copy Markdown
Member Author

Microbenchmark on frozendict | frozendict2 with 50 threads:

Details
import threading
import time
import pyperf
import sys

KEYS = 4_096
LOOPS = 2 ** 9
NTHREAD = 50


code = f"fd = frozendict({', '.join(f'key{key}=1' for key in range(KEYS))})"
exec(code)
assert(len(fd) == KEYS)
assert(all(sys._is_immortal(key) for key in fd.keys()))
fd2 = frozendict(x=1, y=2, z=3)

class Worker(threading.Thread):
    def __init__(self, fd, fd2):
        super().__init__()
        self.copies = 0
        self.fd = fd
        self.fd2 = fd2

    def run(self):
        fd = self.fd
        fd2 = self.fd2
        for _ in range(LOOPS):
            join = fd | fd2

def bench(fd, fd2):
    threads = [Worker(fd, fd2) for _ in range(NTHREAD)]
    for thread in threads:
        thread.start()
    for thread in threads:
        thread.join()

runner = pyperf.Runner()
runner.bench_func('bench', bench, fd, fd2)

Benchmark result: Mean +- std dev: [ref] 554 ms +- 15 ms -> [optim] 112 ms +- 4 ms: 4.95x faster

I ran the benchmark on Fedora 43 on my laptop with 12 threads (6 CPU cores) on a free-threaded Python build.

Copy link
Copy Markdown
Member Author

So far, LGTM, though I am curious about concurrency safety in eliding a critical section when copying a frozendict, especially with a free-threaded interpreter

A frozendict mapping is immutable so a critical section is not needed to ensure that a copy is consistent.

vstinner merged commit 77632f0 into python:main Mar 16, 2026
48 checks passed
vstinner deleted the optim_frozendict_copy branch March 16, 2026 13:19

vstinner commented Mar 16, 2026
edited
Loading

Copy link
Copy Markdown
Member Author

This change increases the scalability on the following operations:

  • frozendict | frozendict2
  • frozendict.copy() on frozendict subclass
  • _PyDict_CopyAsDict(): used by type() and xml.etree.ElementTree.Element constructors to convert a frozendict to a dict

This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
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.

3 participants


Back | FazBrowse Home | New Git URL