From e5f62ec5cd0dde14777754c6ea05034b738f3a1f Mon Sep 17 00:00:00 2001 From: barneygale Date: Sat, 6 Jul 2024 14:36:18 +0100 Subject: [PATCH] GH-119186: Slightly speed up `os.walk(topdown=True)` When `os.walk()` traverses into subdirectories in top-down mode, call `os.path.join()` once to add a trailing slash, and use string concatenation thereafter to generate child paths. --- Lib/os.py | 18 ++++++++++-------- ...4-07-06-14-32-30.gh-issue-119186.E5B1HQ.rst | 2 ++ 2 files changed, 12 insertions(+), 8 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-07-06-14-32-30.gh-issue-119186.E5B1HQ.rst diff --git a/Lib/os.py b/Lib/os.py index 4b48afb040e565..75dd65f88a7077 100644 --- a/Lib/os.py +++ b/Lib/os.py @@ -432,14 +432,16 @@ def walk(top, topdown=True, onerror=None, followlinks=False): # Yield before sub-directory traversal if going top down yield top, dirs, nondirs # Traverse into sub-directories - for dirname in reversed(dirs): - new_path = join(top, dirname) - # bpo-23605: os.path.islink() is used instead of caching - # entry.is_symlink() result during the loop on os.scandir() because - # the caller can replace the directory entry during the "yield" - # above. - if followlinks or not islink(new_path): - stack.append(new_path) + if dirs: + prefix = join(top, top[:0]) # Add trailing slash + for dirname in reversed(dirs): + new_path = prefix + dirname + # bpo-23605: os.path.islink() is used instead of caching + # entry.is_symlink() result during the loop on os.scandir() because + # the caller can replace the directory entry during the "yield" + # above. + if followlinks or not islink(new_path): + stack.append(new_path) else: # Yield after sub-directory traversal if going bottom up stack.append((top, dirs, nondirs)) diff --git a/Misc/NEWS.d/next/Library/2024-07-06-14-32-30.gh-issue-119186.E5B1HQ.rst b/Misc/NEWS.d/next/Library/2024-07-06-14-32-30.gh-issue-119186.E5B1HQ.rst new file mode 100644 index 00000000000000..fbb4f58b59358f --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-07-06-14-32-30.gh-issue-119186.E5B1HQ.rst @@ -0,0 +1,2 @@ +Slightly speed up :func:`os.walk` by calling :func:`os.path.join` less +often.