diff options
author | Barney Gale <barney.gale@gmail.com> | 2024-01-20 03:06:00 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-01-20 03:06:00 (GMT) |
commit | 1e610fb05fa4ba61a759b68461f1a9aed07622fc (patch) | |
tree | 6844d00162d805f022f6f5b69ead966c04e32549 /Lib/pathlib | |
parent | 6313cdde58f34648a430d2830357c9d2a5b67b87 (diff) | |
download | cpython-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.py | 9 |
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 |