Speed up SimpleHTTPRequestHandler.list_directory() by using os.scandir()
Ninguém assumiu esta issue ainda.
- Linguagem predominante
- Python
- Estrelas
- 77.2k
- Forks
- 36k
- Merge médio
- 1d 9h
- PRs com merge (30d)
- 558
Descrição
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
Guia de contribuição
Primeiros passos
- Leia a issue inteira e depois o guia de contribuição do projeto.
- Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
- Faça um fork do repositório e trabalhe em uma branch.
- Abra um pull request que referencie o número da issue.
Direção de pesquisa
Comece por SimpleHTTPRequestHandler.list_directory() e inspecione a suite de testes existente test_httpservers. Compare as verificações das entradas de diretório com o comportamento de os.scandir(), incluindo links simbólicos e casos de fallback, e então execute os testes do servidor HTTP; o trabalho estará concluído quando o comportamento permanecer inalterado enquanto as chamadas a stat por entrada forem reduzidas. Um pull request vinculado já cobre esse trabalho.
Escrita pelo modelo de indexação a partir do texto da issue.
Avaliação
- Stack de tecnologia
- python
- Domínio
- backend, performance, web-dev
- Tipo de issue
- Refatoração
- Dificuldade
- 3/5
- Tempo estimado
- 1-2 dias
- Status de atividade
- Estagnada
- Clareza
- Claramente especificada
- Facilidade para iniciantes
- 25/100