python / python/cpython

Improve performance of inherited mapping assignment slot calls

Ouverte
#156,250 0 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

type-feature
Langage dominant
Python
Étoiles
77.2k
Forks
35.9k
Métriques de merge des PR
Métriques de PR en attente

Description

Feature or enhancement

Proposal:

__setitem__ and __delitem__ share the mp_ass_subscript slot. If a Python subclass of a C mapping overrides only one of them, slot_mp_ass_subscript() is used for both operations.

For example, collections.Counter overrides __delitem__ but inherits dict.__setitem__. Assigning an item looks up the inherited wrapper_descriptor and calls it through the generic tp_call path. Since PyWrapperDescr_Type does not support vectorcall, _PyObject_MakeTpCall() and wrapperdescr_call() each create a temporary argument tuple before reaching dict's C slot.

Reproducer:

from collections import Counter
from time import perf_counter_ns

obj = Counter()

start = perf_counter_ns()
for index in range(20_000_000):
    obj[0] = index

print((perf_counter_ns() - start) / 1_000_000)

On macOS 15.7.1 arm64 with a release build of main (d856402e7176e5a03c5c578f0efc1be968be3257), using two warmups and nine alternating-order samples:

main:      1402.07 ms median (1376.93–1445.12 ms)
prototype:  859.97 ms median (846.24–902.74 ms)

The prototype calls the inherited C slot directly when lookup returns the expected unbound mapping slot wrapper, and otherwise keeps the existing call path. This reduced the benchmark time by 38.66%.

The relevant call-path files are unchanged at b062727097e997bcb900e11503d3248daac903da.

Has this already been discussed elsewhere?

This is a minor feature, which does not need previous discussion elsewhere

Links to previous discussion of this feature:

No response

Linked PRs
  • gh-156258

Guide de contribution

Ouvrir le guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Piste de recherche

Commencez par lire les chemins slot_mp_ass_subscript(), _PyObject_MakeTpCall() et wrapperdescr_call() décrits dans l’issue, puis examinez le PR associé gh-156258. Le travail est terminé lorsque le chemin d’affectation de mapping hérité évite les tuples d’arguments temporaires tout en préservant le fallback existant, et que le benchmark Counter fourni montre l’amélioration signalée.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
python
Domaine
performance
Type d'issue
Fonctionnalité
Difficulté
4/5
Temps estimé
3-5 jours
Activité
À l'abandon
Clarté
Plutôt claire
Accessibilité débutants
35/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.