ShopperCove
Menu
All writingBlogTopicsCategoriesAboutRSS
Blog
Categories
Observability & SRE62All categories
Topics
sre111localhost lab102performance70python58javascript47bundle size36benchmarking35node.js35web development21typescript19benchmark16content creation15All topics
About
Loading article…

ShopperCove

Hands-on notes on developer tools, written after the tool has actually been run.

All writingBlogCategoriesTopicsAboutPrivacyRSS

© 2026 ShopperCove

On this page

  1. Intro — what this post promises
  2. Arms
  3. Lab topology
  4. Lead table — medium (p50 matches/s)
  5. Scale sketch (Path.glob vs listdir+fnmatch)
  6. Glob pattern cost
  7. Reading it
  8. When Path.glob is still right
  9. endswith vs fnmatch
  10. Object tax
  11. Pitfalls
  12. Reproduce
  13. Limits
  14. Takeaway
  1. Blog

Path.glob vs listdir+fnmatch: Localhost Lab

Hands-on Path.glob vs os.listdir+fnmatch.filter one-dir lab: real matches/s on *.py files, measured on Linux localhost today in this hands-on lab for SREs.

1 October 2026·4 min read

Lab
On this page
  1. Intro — what this post promises
  2. Arms
  3. Lab topology
  4. Lead table — medium (p50 matches/s)
  5. Scale sketch (Path.glob vs listdir+fnmatch)
  6. Glob pattern cost
  7. Reading it
  8. When Path.glob is still right
  9. endswith vs fnmatch
  10. Object tax
  11. Pitfalls
  12. Reproduce
  13. Limits
  14. Takeaway

Intro — what this post promises

Match files in one directory: Path.glob('*.py') vs os.listdir + fnmatch.filter. This lab reports matches/s on Linux localhost.

It is not glob-vs-rglob-vs-walk (lab 76) and not fnmatch-vs-re pattern microbenches (lab 93). Focus: Path.glob vs listdir+fnmatch on a single directory.

Related links:

  • 01shoppercove.comglob vs rglob vs walk localhost lab
  • 02shoppercove.comfnmatch vs re localhost lab
  • 03shoppercove.comtomllib vs json localhost lab
  • 04shoppercove.comstat vs path stat localhost lab
  • 05shoppercove.comheapq merge vs sorted localhost lab
  • 06shoppercove.comislice vs list slice localhost lab
  • 07shoppercove.comdataclass replace vs manual localhost lab
  • 08shoppercove.commmap write vs write localhost lab

Lab honesty (1 Oct 2026 IST): Python 3.13.5. Affiliates: 0. Flat dirs only.

Verdict up front (medium 2000 entries / 400 *.py): listdir+endswith ~721109 matches/s; listdir+fnmatch ~526570; Path.glob ~294091; Path.iterdir+suffix ~61488.


Arms

ArmPattern
Path.glob('*.py')pathlib
listdir + fnmatch.filterclassic
listdir + endswith('.py')fixed suffix fast path
scandir + endswithDirEntry
Path.iterdir + .suffixpathlib scan

Lab topology

small 200/40 · medium 2000/400 · large 8000/1600 · 7 rounds · p50
metric: matches/s = n_match / p50_s

Script: lab-evidence/113-path-glob-vs-fnmatch/results/run_lab.py.


Lead table — medium (p50 matches/s)

Armmatches/sentries/s
listdir + endswith7211093605546
scandir + endswith6229373114687
listdir + fnmatch5265702632850
Path.glob2940911470453
Path.iterdir + suffix61488307440

Scale sketch (Path.glob vs listdir+fnmatch)

SizePath.globlistdir+fnmatch
small295655485484
medium294091526570
large287243554569

Glob pattern cost

*.py is a cheap filter. Patterns with multiple * / ? classes push more work into fnmatch — still usually dominated by directory listing syscall cost on large folders. Re-measure if your matcher is ** recursive (again: lab 76).


Reading it

  • Simple *.ext on one dir → listdir/scandir + endswith leads here.
  • Need glob wildcards beyond a suffix → fnmatch or Path.glob.
  • Path.glob stays convenient and mid-pack; fine for tooling scripts.
  • Recursive trees → lab 76 (rglob / walk), not this post.

When Path.glob is still right

Tooling scripts that already speak pathlib, need brace-free relative patterns, or may later grow a single * directory segment often stay on Path.glob for clarity. The ~2× gap vs listdir+fnmatch on medium here rarely matters unless you scan directories in a tight loop.


endswith vs fnmatch

endswith(".py") is not a glob. It misses patterns like test_*.py or *.pyc exclusions. Use it only for fixed-suffix filters; otherwise fnmatch.filter / Path.glob keep semantics honest. Lab 93 covers pattern-engine speed in isolation — not directory IO.


Object tax

Path.iterdir() yielding Path objects paid a clear tax versus name-only listdir/scandir arms. If you only need filenames for a filter, keep strings until you must touch the filesystem again.


Pitfalls

  • Using Path.iterdir lists when you only need names (Path object tax showed up here).
  • Running rglob accidentally when one directory was intended.
  • Treating fnmatch pattern speed (lab 93) as directory listing speed.
  • Ignoring locale/case rules on case-insensitive filesystems.

Reproduce

python3 lab-evidence/113-path-glob-vs-fnmatch/results/run_lab.py

Evidence: summary.json, summary.txt, tree/.

For CI file collectors, scandir+endswith on a fixed suffix is a good default; graduate to fnmatch/Path.glob when patterns get expressive.

Always verify match counts against a known fixture before trusting a faster filter in production sweeps.


Limits

One Linux box. Flat synthetic directories. Pattern fixed to *.py. Not networked FS.


Takeaway

At 2000 entries, listdir+fnmatch ~526570 matches/s beat Path.glob ~294091; plain endswith ~721109 led for suffix-only filters. Use Path.glob for ergonomics; listdir+fnmatch/endswith when directory scans are hot.

path.globfnmatch.filteros.listdirpathlibdirectory globlocalhost labsrematches/s

Lab evidence

What I found running this

Lab 1 Oct 2026 IST. Python 3.13.5. medium 2000/400: listdir_fnmatch 526570 matches/s; Path.glob 294091; endswith 721109. One dir only — not lab 76/93. Affiliates: 0. Evidence: lab-evidence/113-path-glob-vs-fnmatch/.

Notes when a lab post goes up

Occasional email for new hands-on reviews. No sequence and no sponsors.

Keep reading

  • os.stat vs Path.stat vs lstat: Localhost Lab

    Hands-on os.stat vs pathlib.Path.stat vs os.lstat: real metadata stats/s on many regular files, measured on Linux localhost in this hands-on lab for SREs.

    Lab1 Oct 20264 min read

  • fnmatch vs re Name Filter: Localhost Lab

    Hands-on fnmatch.filter vs re.compile name-list filtering measured on Linux localhost.

    Lab1 Oct 20264 min read

  • scandir vs listdir in Python: Which Is Faster? Tested

    Hands-on os.scandir vs listdir vs Path.iterdir lab: real entries/s for names and is_file on a synthetic tree, measured on Linux localhost (lab) for SREs.

    Lab1 Oct 20264 min read