summaryrefslogtreecommitdiffstats
path: root/Lib/pathlib
diff options
context:
space:
mode:
authorBarney Gale <barney.gale@gmail.com>2024-01-20 03:06:00 (GMT)
committerGitHub <noreply@github.com>2024-01-20 03:06:00 (GMT)
commit1e610fb05fa4ba61a759b68461f1a9aed07622fc (patch)
tree6844d00162d805f022f6f5b69ead966c04e32549 /Lib/pathlib
parent6313cdde58f34648a430d2830357c9d2a5b67b87 (diff)
downloadcpython-1e610fb05fa4ba61a759b68461f1a9aed07622fc.zip
cpython-1e610fb05fa4ba61a759b68461f1a9aed07622fc.tar.gz
cpython-1e610fb05fa4ba61a759b68461f1a9aed07622fc.tar.bz2
GH-113225: Speed up `pathlib.Path.walk(top_down=False)` (#113693)
Use `_make_child_entry()` rather than `_make_child_relpath()` to retrieve path objects for directories to visit. This saves the allocation of one path object per directory in user subclasses of `PathBase`, and avoids a second loop. This trick does not apply when walking top-down, because users can affect the walk by modifying *dirnames* in-place. A side effect of this change is that, in bottom-up mode, subdirectories of each directory are visited in reverse order, and that this order doesn't match that of the names in *dirnames*. I suspect this is fine as the order is arbitrary anyway.
Diffstat (limited to 'Lib/pathlib')
-rw-r--r--Lib/pathlib/_abc.py9
1 files changed, 5 insertions, 4 deletions
diff --git a/Lib/pathlib/_abc.py b/Lib/pathlib/_abc.py
index e5eeb4a..553e1a3 100644
--- a/Lib/pathlib/_abc.py
+++ b/Lib/pathlib/_abc.py
@@ -820,6 +820,8 @@ class PathBase(PurePathBase):
with scandir_obj as scandir_it:
dirnames = []
filenames = []
+ if not top_down:
+ paths.append((path, dirnames, filenames))
for entry in scandir_it:
try:
is_dir = entry.is_dir(follow_symlinks=follow_symlinks)
@@ -828,16 +830,15 @@ class PathBase(PurePathBase):
is_dir = False
if is_dir:
+ if not top_down:
+ paths.append(path._make_child_entry(entry))
dirnames.append(entry.name)
else:
filenames.append(entry.name)
if top_down:
yield path, dirnames, filenames
- else:
- paths.append((path, dirnames, filenames))
-
- paths += [path._make_child_relpath(d) for d in reversed(dirnames)]
+ paths += [path._make_child_relpath(d) for d in reversed(dirnames)]
def absolute(self):
"""Return an absolute version of this path