Skip to content

Extend FOR_ITER specializations to cover other indexable sequences #145668

Open

Description

@markshannon

Currently, we specialize FOR_ITER for both tuple and list. We also handle tuple and lists specially in GET_ITER to support this specialization.

We should extend this specialization of iteration over sequences, using virtual iterators to bytes, str, bytesarray and others.
To do this, we should:

  • Add a tp_getiteritem slots to PyTypeObject for sequences that can be efficiently indexed and cannot raise except for out-of-bounds access.
  • Add a specialization of FOR_ITER for these classes.
  • Specialize GET_ITER for:
    • iterators
    • indexable sequences (those classes with a tp_getiteritem slot)
  • Specialize SEND for indexable sequences which should also improve JIT coverage, as unspecialized _SEND is currently a major cause of jit optimization failures.

Combined with #145667 this will allow effective specialization of a wider range of iterables and allow that specialization not only for for loops, but also for yield from loops.
It will add 3 instructions (4 new, 1 removed) which a reasonable

Linked PRs

Activity

  1. added
    performancePerformance or resource usage
    interpreter-core(Objects, Python, Grammar, and Parser dirs)
    3.15bugs and security fixes
    on Mar 9, 2026
  2. MrEx3cut0r commented on Mar 9, 2026

    @MrEx3cut0r

    @markshannon hi! I`d like to work on it

  3. added 2 commits that reference this issue on Mar 9, 2026
  4. markshannon commented on Mar 17, 2026

    @markshannon
    MemberAuthor

    Here is a more detailed, and slightly changed design.

    The tp_getiteritem function pointer slot

    It is probably too limiting to only allow contiguous sequences that cannot raise. It would prevents iteration over strings (can raise if cannot allocate new string) and others that might occasionally raise.
    We additionally specialize for lists and tuples, so it makes sense to broaden virtual iteration as it won't negatively impact the performance of lists and tuples.

    The signature is PyObject *tp_getiteritem(PyObject *iterable, intptr_t *index). The VM will initialize the index to 0 at the start of iteration, thereafter the index is under the control of tp_getiteritem. The returned value is the next item in the iteration. If NULL is returned, iteration is complete if *index >= 0 and an error has occurred if *index < 0. If iteration is complete, no exception should be set. StopIteration should never be raised.

    tp_getiteritem cannot handle dicts, or sets, as we won't be able to spot concurrent modification, but it will be able to handle frozendicts and frozensets.

    Specialization of GET_ITER

    GET_ITER should gain specializations for:

    • Iterators: Py_TYPE(obj)->tp_iter == PyObject_SelfIter
    • Virtual iterators: Py_TYPE(obj)->tp_iteritem != NULL

    Specialization of SEND

    SEND should gain a specializations for virtual iterators: Py_TYPE(obj)->tp_iteritem != NULL

  5. brijkapadia commented on Mar 24, 2026

    @brijkapadia
    Contributor

    @MrEx3cut0r Are you still working on this or could I try to take a stab at this.

  6. MrEx3cut0r commented on Mar 24, 2026

    @MrEx3cut0r

    @bkap123 you can take it, i have no time for it

  7. added a commit that references this issue on Apr 16, 2026
  8. added a commit that references this issue on Apr 25, 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

    3.15bugs and security fixesinterpreter-core(Objects, Python, Grammar, and Parser dirs)performancePerformance or resource usage

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions