GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Free-threaded build: deque iteration and `list(deque)` take a critical section per item · Issue #161850 · python/cpython

Free-threaded build: deque iteration and list(deque) take a critical section per item #161850

New issue
Copy link
New issue
Copy link
Open
#161854
Open
Free-threaded build: deque iteration and list(deque) take a critical section per item#161850
#161854
Copy link
Labels
interpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)performancePerformance or resource usagePerformance or resource usagetype-featureA feature request or enhancementA feature request or enhancement

Description

@113xiaoji
113xiaoji
opened on Nov 12, 2026
Issue body actions

Feature or enhancement

In the free-threaded build, advancing a collections.deque iterator enters a two-object critical section on the iterator and the deque (dequeiter_next, dequereviter_next, dequeiter_reduce), which normally acquires and releases both mutexes in the uncontended path.

Materializing a deque does this for every item. This covers list(d), [*d], lst.extend(d), and PySequence_Fast(d), and therefore also ''.join(d), which passes the deque's iterator to list.extend().

This repeated synchronization is costly on the tested Kunpeng 950 (AArch64, LSE). In a hot, uncontended 8-bit CAS-pair C loop, the measured CPU cost was about 10 ns per logical CAS on the 950 and 2.5 ns on an EPYC 9654; these figures include loop/accounting work and are not isolated instruction latencies. Mako's buffer is a deque joined with ''.join(), and its bm_mako render took about 2.26 times as long in the free-threaded build as in the default build on the 950.

Two independent improvements:

  1. Lock only the deque when advancing an iterator. All writes to the iterator's fields already happen under the deque's lock, so that lock alone serializes concurrent next() calls on a shared iterator.
  2. Copy a deque into a list under one critical section. Add a fast path in list.extend() for deques and forward deque iterators, the same way list.extend() already handles sets and dicts. Since the deque type lives in _collections, the module registers the fast path with listobject.c.

Measured on 3.14.6, PGO+LTO, GCC 12.3.1, pinned to one core. Times are in µs for a deque of 1000 strings, on the Kunpeng 950:

Operation free-threaded before free-threaded after default before default after
''.join(d) 54.8 9.4 8.8 5.9
list(d) 50.3 5.1 4.7 1.8
for x in d: pass 52.3 30.6 6.4 6.4

bm_mako (unmodified Mako 1.1.4) on the free-threaded build, before → after:

  • Kunpeng 950: 19.09 → 12.75 ms (−33%)
  • EPYC 9654: 10.15 → 9.21 ms (−9%)

The default build also gets slightly faster.

The proposed branches target CPython main. The measurements above are from a CPython 3.14.6 backport of both changes; they are not measurements of the main-branch port.

Has this already been discussed elsewhere?

No response given

Links to previous discussion of this feature:

No response

Linked PRs

  • gh-161850: Lock only the deque when advancing a deque iterator #161853
  • gh-161850: Copy a deque into a list under a single critical section #161854

Activity

  1. 113xiaoji
    added
    type-featureA feature request or enhancementA feature request or enhancement
    on Nov 12, 2026
  2. 113xiaoji
    closed this as completedon Nov 12, 2026
  3. 113xiaoji
    reopened this on Nov 12, 2026
  4. 113xiaoji
    added a commit that references this issue on Nov 12, 2026

    fix: store deque hooks per interpreter

    b83e424
  5. picnixz
    added
    performancePerformance or resource usagePerformance or resource usage
    interpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)
    on Nov 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    interpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)performancePerformance or resource usagePerformance or resource usagetype-featureA feature request or enhancementA feature request or enhancement

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      You are visitor 01402503 — GeezerVison does not store the pages you look up.
      Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.