GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — gh-118761: Speedup pathlib import by deferring shutil by danielhollas · Pull Request #123520 · python/cpython

Conversation

@danielhollas

@danielhollas danielhollas commented Aug 30, 2024 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

~15% of pathlib import time (1.6ms on my machine) is spent on importing shutil. Since this module is only used in one place it makes sense to defer its import. Incidentally, this also makes the code more explicit imho, it took me a while to understand how the current code works.

image

  • Issue: Improve import time of various stdlib modules #118761

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

barneygale reacted with thumbs up emoji
All reactions
  • 👍 1 reaction
@danielhollas
Speedup pathlib import by deffering shutil
59b5bd0
@danielhollas
danielhollas requested a review from barneygale as a code owner August 30, 2024 21:16
@bedevere-app bedevere-app Bot mentioned this pull request Aug 30, 2024
Improve import time of various stdlib modules #118761
Closed
@bedevere-app bedevere-app Bot added the awaiting review label Aug 30, 2024
blurb-it Bot and others added 2 commits August 31, 2024 11:12
@blurb-it
📜🤖 Added by blurb_it.
3957097
@danielhollas
Merge branch 'main' into speedup-pathlib
2a180bc
@hugovk hugovk changed the title gh-118761: Speedup pathlib import by deffering shutil gh-118761: Speedup pathlib import by deferring shutil Aug 31, 2024
picnixz
picnixz reviewed Aug 31, 2024
View reviewed changes

@picnixz picnixz left a comment •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On main in a non-debug build (but not a PGO one), I get no improvements at all.

The command to run is ./python -m pyperf timeit 'import pathlib' -l 1 -w 0 -n 1 -p 250. This will ensure that you don't have warmups and don't have cached modules.

  • main: Mean +- std dev: 1.37 ms +- 0.05 ms
  • PR: Mean +- std dev: 1.36 ms +- 0.04 ms

I'm not sure this is worth the change but maybe I'm incorrectly benchmarking the time.

Some idea: shutil imports some additional libs such as fnmatch that are then needed by glob. So when you do from glob import _StringGlobber after import shutil, you'll end up importing fnmatch. So you save the fnmatch import in the glob module by importing shutil. Now I don't know if this specific import is the reason why I don't see an improvement.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread Misc/NEWS.d/next/Library/2024-08-31-11-12-49.gh-issue-118761.Ai_Ma1.rst Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread Lib/pathlib/_local.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

hugovk
hugovk reviewed Aug 31, 2024
View reviewed changes
Comment thread Lib/pathlib/_local.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

@barneygale

barneygale commented Aug 31, 2024

Copy link
Copy Markdown
Contributor

I think this probably shouldn't have a NEWS entry, because the import shutil was introduced only a couple of weeks ago, and there have been no releases from the main branch in that time. A user reading about a 15% performance improvement could be misled.

danielhollas reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@barneygale barneygale added the skip news label Aug 31, 2024
@danielhollas

danielhollas commented Aug 31, 2024

Copy link
Copy Markdown
Contributor Author

The command to run is ./python -m pyperf timeit 'import pathlib' -l 1 -w 0 -n 1 -p 250. This will ensure that you don't have warmups and don't have cached modules.

1.6ms seems suspiciously fast, are you sure the module is not being cached?

I don't think fnmatch is the issue here, I think in the icicle graph I posted above it is already counted as part of glob. Most of the import time of shutil comes from importing compression modules, lzma etc. Measured with python -Ximporttime -c 'import pathlib'. I think I used the PGO build, not sure what is the recommended build for benchmarking.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

hugovk
hugovk reviewed Aug 31, 2024
View reviewed changes
Comment thread Lib/pathlib/_local.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

@hugovk

hugovk commented Aug 31, 2024 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

I think I used the PGO build, not sure what is the recommended build for benchmarking.

Ideally use PGO+LTO.

On macOS with PGO+LTO, running ./python.exe -X importtime -c "import pathlib", the pathlib import takes 7 ms with main and 6 ms with this PR.

You can see the big shutil block is missing underneath pathlib._local afterwards in the tuna importtime visualisations (I ran ./python.exe -c "import pathlib" && ./python.exe -X importtime -c "import pathlib" 2> import.log && tuna import.log):

Before:

image

After:

image

And with hyperfine, this branch is about 1.5 ms faster than main:

❯ hyperfine --warmup 32 \
--prepare "git checkout speedup-pathlib"  './python.exe -c "import pathlib"' \
--prepare "git checkout main"             './python.exe -c "import    pathlib"'
Benchmark 1: ./python.exe -c "import pathlib"
  Time (mean ± σ):      14.8 ms ±   0.6 ms    [User: 11.9 ms, System: 2.4 ms]
  Range (min … max):    14.1 ms …  18.2 ms    96 runs

  Warning: Statistical outliers were detected. Consider re-running this benchmark on a quiet system without any interferences from other programs.

Benchmark 2: ./python.exe -c "import    pathlib"
  Time (mean ± σ):      16.4 ms ±   0.8 ms    [User: 13.1 ms, System: 2.7 ms]
  Range (min … max):    15.6 ms …  23.2 ms    91 runs

  Warning: Statistical outliers were detected. Consider re-running this benchmark on a quiet system without any interferences from other programs.

Summary
  ./python.exe -c "import pathlib" ran
    1.11 ± 0.07 times faster than ./python.exe -c "import    pathlib"
danielhollas reacted with heart emoji
All reactions
  • ❤️ 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

danielhollas and others added 2 commits August 31, 2024 19:34
@danielhollas @hugovk
Update Lib/pathlib/_local.py
496e0ac
Co-authored-by: Hugo van Kemenade <[email protected]>
@danielhollas
Delete News entry
889836d
danielhollas
danielhollas commented Aug 31, 2024
View reviewed changes
Comment thread Lib/pathlib/_local.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

@danielhollas
remove path keyword
0067d84
@danielhollas

danielhollas commented Aug 31, 2024

Copy link
Copy Markdown
Contributor Author

Thank you all for the reviews, I believe I addressed all the comments.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

AA-Turner
AA-Turner approved these changes Sep 1, 2024
View reviewed changes
@bedevere-app bedevere-app Bot added awaiting merge and removed awaiting review labels Sep 1, 2024
@picnixz

picnixz commented Sep 1, 2024 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

1.6ms seems suspiciously fast, are you sure the module is not being cached?

With a caching it's in the realm of nanoseconds on my laptop. But my specs are a bit... biaised sometimes:

OS: openSUSE Leap 15.5 x86_64
Host: ROG Strix G814JZ_G814JZ 1.0
Kernel: 5.14.21-150500.55.73-default
CPU: 13th Gen Intel i9-13980HX (32) @ 5.400GHz
GPU: NVIDIA GeForce RTX 4080 Max-Q / Mobile
GPU: Intel Raptor Lake-S UHD Graphics
Memory: 4124MiB / 31698MiB

EDIT: It's a bit weird that pyperf reports timings in the realm of 1.6 ms but hyperfine does not:

Benchmark 1: ./python -c "import pathlib"
  Time (mean ± σ):      11.5 ms ±   2.1 ms    [User: 9.7 ms, System: 1.9 ms]
  Range (min … max):    10.2 ms …  20.8 ms    157 runs

  Warning: Statistical outliers were detected. Consider re-running this benchmark on a quiet system without any interferences from other programs.

Benchmark 2: ./python -c "import    pathlib"
  Time (mean ± σ):      11.9 ms ±   1.3 ms    [User: 10.5 ms, System: 1.4 ms]
  Range (min … max):    11.0 ms …  21.7 ms    149 runs

  Warning: Statistical outliers were detected. Consider re-running this benchmark on a quiet system without any interferences from other programs.

Summary
  './python -c "import pathlib"' ran
    1.03 ± 0.22 times faster than './python -c "import    pathlib"'

I'm approving the PR though it does not really change on my system much. But since it may affect other users, I think it's worth the change.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

picnixz
picnixz approved these changes Sep 1, 2024
View reviewed changes
@barneygale

barneygale commented Sep 1, 2024

Copy link
Copy Markdown
Contributor

Thanks for this!

danielhollas reacted with heart emoji
All reactions
  • ❤️ 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@barneygale
barneygale merged commit 2304774 into python:main Sep 1, 2024
@bedevere-app bedevere-app Bot removed the awaiting merge label Sep 1, 2024
@danielhollas
danielhollas deleted the speedup-pathlib branch September 1, 2024 14:46
@danielhollas

danielhollas commented Sep 1, 2024

Copy link
Copy Markdown
Contributor Author

EDIT: It's a bit weird that pyperf reports timings in the realm of 1.6 ms but hyperfine does not:

hyperfine also measures the overhead of python startup.

Another possible explanation why you don't see a difference, do you have the compression modules available? You can try python -c "import lzma; import zlib; import bz2

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@picnixz

picnixz commented Sep 1, 2024

Copy link
Copy Markdown
Member

I do have them available :( it's an interesting observation though but it's my problem I think.

danielhollas reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@danielhollas danielhollas mentioned this pull request Apr 27, 2025
gh-118761: Add test_lazy_import for more modules #133057
Merged
@hugovk hugovk mentioned this pull request Mar 23, 2026
gh-137855: Improve import time of pathlib #146327
Merged
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@hugovk hugovk hugovk left review comments
@AA-Turner AA-Turner AA-Turner approved these changes
@picnixz picnixz picnixz approved these changes
@barneygale barneygale Awaiting requested review from barneygale barneygale is a code owner

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

skip news

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

5 participants

@danielhollas @barneygale @hugovk @picnixz @AA-Turner
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.