Speed up SimpleHTTPRequestHandler.list_directory() by using os.scandir()
Dieses Issue hat noch niemand übernommen.
- Vorherrschende Sprache
- Python
- Sterne
- 77.2k
- Forks
- 35.9k
- PR-Merge-Kennzahlen
- PR-Kennzahlen ausstehend
Beschreibung
SimpleHTTPRequestHandler.list_directory() calls os.listdir() and then, for every entry, os.path.isdir() (a stat) and os.path.islink() (an lstat) — two stat-family syscalls per entry. This is wasted work on any filesystem and dominates listing time for large directories; on network filesystems like NFS, where each call is a round-trip, it becomes severe.
os.scandir() returns the entry type from the directory read itself (POSIX d_type / NFS READDIRPLUS), eliminating the per-entry stats in the common case. CPython already did this migration for os.walk(), glob, and pathlib.Path.iterdir() (gh-117727); http.server was missed.
Benchmark
Directory with 1000 files + 1000 dirs (plus a few symlinks):
- stat-family syscalls (
strace): 4088 → 88 (the 88 is constant interpreter startup; the per-entry loop drops from ~2 syscalls to ~0) - local filesystem wall-clock: ~10× faster
- emulating NFS by injecting per-
statlatency: the listing goes from seconds to ~2 ms
Worst case — a mount that returns DT_UNKNOWN — falls back to one cached lstat per entry, which is still fewer calls than today and never worse.
The change is behavior-preserving: DirEntry.is_dir()/is_symlink() match os.path.isdir/os.path.islink semantics (follow-symlinks behavior and return-False-on-error), verified across real dirs/files, symlink-to-dir, symlink-to-file, and broken symlinks. The existing test_httpservers suite passes unchanged.
I have a patch ready and will open a PR.
This issue was prepared with AI assistance (Claude Code); the analysis and benchmarks were reviewed by me.
Linked PRs
- gh-151789
Beitragsleitfaden
Erste Schritte
- Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
- Forke das Repository und arbeite in einem Branch.
- Öffne einen Pull Request, der die Issue-Nummer nennt.
Rechercherichtung
Beginne bei SimpleHTTPRequestHandler.list_directory() und untersuche die bestehende Testsuite test_httpservers. Vergleiche die Prüfungen der Verzeichniseinträge mit dem Verhalten von os.scandir(), einschließlich Symlinks und Fallback-Fällen, und führe anschließend die HTTP-Server-Tests aus; die Arbeit ist abgeschlossen, wenn das Verhalten unverändert bleibt und die stat-Aufrufe pro Eintrag reduziert werden. Ein verlinkter Pull Request deckt diese Arbeit bereits ab.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Bewertung
- Tech-Stack
- python
- Bereich
- backend, performance, web-dev
- Issue-Typ
- Refactoring
- Schwierigkeit
- 3/5
- Geschätzter Aufwand
- 1-2 Tage
- Aktivitätsstatus
- Veraltet
- Klarheit
- Klar beschrieben
- Anfängerfreundlichkeit
- 25/100