python / python/cpython

Performance regression of pathlib.Path hashing

Aperta
#138,407 19 commenti 1 reazione 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

performance stdlib topic-pathlib type-bug
Lingua principale
Python
Stelle
77.2k
Fork
35.9k
Metriche di merge delle PR
Metriche PR in attesa

Descrizione

Bug report

Bug description:

Converting a list of pathlib.Path objects to a set() takes significantly more time in python 3.12 and beyond compared to 3.11.

The below code is a minimal reproduction:


from pathlib import Path
import time
import sys

print(sys.version)

# make 6000 paths as a string
paths_str = ["/tmp/foo/bar/{i}" for i in range(1000, 7000)]

t = time.perf_counter()
# convert it to a list of Path objects
paths_path = [Path(path) for path in paths_str]

elapsed = time.perf_counter() - t
print(f"List construct: {int(elapsed * 1000)} msec")

# convert list to set
t = time.perf_counter()
set(paths_path)
elapsed = time.perf_counter() - t
print(f"Set conversion: {int(elapsed * 1000)} msec")


# extra step: convert list to set (demonstrate caching makes it faster)
t = time.perf_counter()
set(paths_path)
elapsed = time.perf_counter() - t
print(f"Set conversion (cached): {int(elapsed * 1000)} msec")

It shows with 3.12:

3.12.11 (main, Jun  3 2025, 15:41:47) [GCC 14.3.0]
List construct: 5 msec
Set conversion: 28 msec
Set conversion (cached): 1 msec

With 3.14rc1 (similar):

3.14.0rc1 (main, Jul 22 2025, 16:42:44) [GCC 14.3.0]
List construct: 4 msec
Set conversion: 26 msec
Set conversion (cached): 1 msec

But with python 3.11 (faster):

3.11.13 (main, Jun  3 2025, 18:38:25) [GCC 14.3.0]
List construct: 12 msec
Set conversion: 8 msec
Set conversion (cached): 1 msec

I also found that not only hash() got worse but str() as well - if you replace the set() call with a [str(p) for p in paths_path].

I found a possible candidate for this issue, but that's more just a theory, I could not test it:
https://github.com/python/cpython/commit/a68e585c8b7b27323f67905868467ce0588a1dae

Could you please check what causes this?
I think newer python versions should not make the code slower, pathlib.Path is a great object (much superior than str) and now using lots of paths with a set or dict (which are also powerful data structures) kills the performance.

If you need any help, let me know.

Thank you,
Zsolt

CPython versions tested on:

3.12

Operating systems tested on:

Linux

Linked PRs
  • gh-138645

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Direzione di ricerca

Inizia con il benchmark segnalato di pathlib.Path, confrontando l'hashing e la conversione in stringa in Python 3.11, 3.12 e 3.14. Esamina il commit sospetto a68e585c8b7b27323f67905868467ce0588a1dae e la PR collegata gh-138645. Il lavoro è completato quando la regressione è stata identificata e sono state ripristinate prestazioni comparabili per set, hash e conversione in stringa.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
python
Ambito
performance
Tipo di issue
Bug
Difficoltà
4/5
Tempo stimato
3-5 giorni
Stato di attività
Ferma
Chiarezza
Abbastanza chiara
Idoneità per principianti
25/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.