Skip to content

Conversation

@donbarbos
Copy link
Contributor

@donbarbosdonbarbos commented Feb 7, 2025

  • Improve import time modules by lazy import warnings.
  • Remove unused warnings and struct from Lib/ctypes/_layout.py.

My hyperfine benchmarks:

First experiment in Main branch

➜ cpython git:(43e0240213) ✗ hyperfine --warmup 11"./python -c 'import codeop'""./python -c 'import zipimport'""./python -c 'import ctypes'""./python -c 'import hmac'""./python -c 'import importlib'""./python -c 'import logging'""./python -c 'import pkgutil'""./python -c 'import pydoc'""./python -c 'import rlcompleter'""./python -c 'import ssl'""./python -c 'import tempfile'""./python -c 'import traceback'""./python -c 'import urllib'""./python -c 'import xml'" Benchmark 1: ./python -c 'import codeop' Time (mean ± σ): 24.6ms± 1.0ms[User: 21.8 ms, System: 2.7 ms] Range (min … max): 23.4ms… 32.9ms112 runs 

Warning: Statistical outliers were detected. Consider re-running this benchmark on a quiet system without any interferences from other programs. It might help to use the '--warmup' or '--prepare' options.

Benchmark 2: ./python -c 'import zipimport'
Time (mean ± σ): 22.7ms± 0.8ms[User: 20.0 ms, System: 2.6 ms]
Range (min … max): 21.8ms… 28.6ms128 runs

Warning: Statistical outliers were detected. Consider re-running this benchmark on a quiet system without any interferences from other programs. It might help to use the '--warmup' or '--prepare' options.

Benchmark 3: ./python -c 'import ctypes'
Time (mean ± σ): 27.4ms± 0.5ms[User: 24.1 ms, System: 3.2 ms]
Range (min … max): 26.5ms… 29.3ms108 runs

Benchmark 4: ./python -c 'import hmac'
Time (mean ± σ): 27.2ms± 0.5ms[User: 23.8 ms, System: 3.3 ms]
Range (min … max): 26.3ms… 28.9ms108 runs

Benchmark 5: ./python -c 'import importlib'
Time (mean ± σ): 23.1ms± 0.9ms[User: 20.3 ms, System: 2.6 ms]
Range (min … max): 22.1ms… 31.3ms122 runs

Warning: Statistical outliers were detected. Consider re-running this benchmark on a quiet system without any interferences from other programs. It might help to use the '--warmup' or '--prepare' options.

Benchmark 6: ./python -c 'import logging'
Time (mean ± σ): 51.9ms± 0.6ms[User: 47.8 ms, System: 4.0 ms]
Range (min … max): 50.6ms… 53.4ms56 runs

Benchmark 7: ./python -c 'import pkgutil'
Time (mean ± σ): 52.2ms± 0.9ms[User: 48.3 ms, System: 3.8 ms]
Range (min … max): 50.4ms… 54.8ms58 runs

Benchmark 8: ./python -c 'import pydoc'
Time (mean ± σ): 89.2ms± 1.7ms[User: 83.4 ms, System: 5.6 ms]
Range (min … max): 87.2ms… 95.0ms34 runs

Benchmark 9: ./python -c 'import rlcompleter'
Time (mean ± σ): 61.8ms± 1.1ms[User: 57.0 ms, System: 4.6 ms]
Range (min … max): 60.1ms… 65.8ms49 runs

Benchmark 10: ./python -c 'import ssl'
Time (mean ± σ): 47.6ms± 1.8ms[User: 43.1 ms, System: 4.3 ms]
Range (min … max): 45.1ms… 57.6ms63 runs

Benchmark 11: ./python -c 'import tempfile'
Time (mean ± σ): 47.2ms± 1.1ms[User: 42.9 ms, System: 4.3 ms]
Range (min … max): 45.2ms… 49.9ms63 runs

Benchmark 12: ./python -c 'import traceback'
Time (mean ± σ): 43.5ms± 1.2ms[User: 39.8 ms, System: 3.5 ms]
Range (min … max): 41.7ms… 46.8ms65 runs

Benchmark 13: ./python -c 'import urllib'
Time (mean ± σ): 25.9ms± 1.7ms[User: 22.8 ms, System: 2.9 ms]
Range (min … max): 22.5ms… 34.3ms128 runs

Benchmark 14: ./python -c 'import xml'
Time (mean ± σ): 26.2ms± 0.9ms[User: 23.5 ms, System: 2.6 ms]
Range (min … max): 24.5ms… 29.2ms114 runs

Summary
./python -c 'import zipimport' ran
1.02 ± 0.05 times faster than ./python -c 'import importlib'
1.08 ± 0.06 times faster than ./python -c 'import codeop'
1.14 ± 0.09 times faster than ./python -c 'import urllib'
1.16 ± 0.06 times faster than ./python -c 'import xml'
1.20 ± 0.05 times faster than ./python -c 'import hmac'
1.21 ± 0.05 times faster than ./python -c 'import ctypes'
1.92 ± 0.09 times faster than ./python -c 'import traceback'
2.08 ± 0.09 times faster than ./python -c 'import tempfile'
2.10 ± 0.11 times faster than ./python -c 'import ssl'
2.29 ± 0.09 times faster than ./python -c 'import logging'
2.30 ± 0.09 times faster than ./python -c 'import pkgutil'
2.72 ± 0.11 times faster than ./python -c 'import rlcompleter'
3.93 ± 0.16 times faster than ./python -c 'import pydoc'

Second experiment in Main branch

➜ cpython git:(43e0240213) ✗ hyperfine --warmup 11"./python -c 'import codeop'""./python -c 'import zipimport'""./python -c 'import ctypes'""./python -c 'import hmac'""./python -c 'import importlib'""./python -c 'import logging'""./python -c 'import pkgutil'""./python -c 'import pydoc'""./python -c 'import rlcompleter'""./python -c 'import ssl'""./python -c 'import tempfile'""./python -c 'import traceback'""./python -c 'import urllib'""./python -c 'import xml'" Benchmark 1: ./python -c 'import codeop' Time (mean ± σ): 24.5ms± 1.6ms[User: 21.7 ms, System: 2.8 ms] Range (min … max): 23.5ms… 39.7ms119 runs 

Warning: Statistical outliers were detected. Consider re-running this benchmark on a quiet system without any interferences from other programs. It might help to use the '--warmup' or '--prepare' options.

Benchmark 2: ./python -c 'import zipimport'
Time (mean ± σ): 22.8ms± 1.0ms[User: 20.4 ms, System: 2.3 ms]
Range (min … max): 21.7ms… 30.3ms129 runs

Warning: Statistical outliers were detected. Consider re-running this benchmark on a quiet system without any interferences from other programs. It might help to use the '--warmup' or '--prepare' options.

Benchmark 3: ./python -c 'import ctypes'
Time (mean ± σ): 27.6ms± 0.9ms[User: 24.5 ms, System: 2.9 ms]
Range (min … max): 26.5ms… 34.3ms105 runs

Warning: Statistical outliers were detected. Consider re-running this benchmark on a quiet system without any interferences from other programs. It might help to use the '--warmup' or '--prepare' options.

Benchmark 4: ./python -c 'import hmac'
Time (mean ± σ): 27.1ms± 0.6ms[User: 23.7 ms, System: 3.3 ms]
Range (min … max): 26.2ms… 28.8ms108 runs

Benchmark 5: ./python -c 'import importlib'
Time (mean ± σ): 23.9ms± 1.2ms[User: 21.4 ms, System: 2.3 ms]
Range (min … max): 22.0ms… 26.4ms126 runs

Benchmark 6: ./python -c 'import logging'
Time (mean ± σ): 59.0ms± 2.9ms[User: 54.6 ms, System: 4.3 ms]
Range (min … max): 56.5ms… 73.0ms52 runs

Benchmark 7: ./python -c 'import pkgutil'
Time (mean ± σ): 61.2ms± 3.9ms[User: 56.1 ms, System: 5.0 ms]
Range (min … max): 55.4ms… 68.4ms53 runs

Benchmark 8: ./python -c 'import pydoc'
Time (mean ± σ): 114.4ms± 3.4ms[User: 106.5 ms, System: 7.7 ms]
Range (min … max): 111.3ms… 122.7ms26 runs

Benchmark 9: ./python -c 'import rlcompleter'
Time (mean ± σ): 78.8ms± 1.2ms[User: 72.5 ms, System: 6.1 ms]
Range (min … max): 76.7ms… 81.0ms38 runs

Benchmark 10: ./python -c 'import ssl'
Time (mean ± σ): 58.8ms± 0.9ms[User: 53.4 ms, System: 5.3 ms]
Range (min … max): 57.4ms… 61.6ms50 runs

Benchmark 11: ./python -c 'import tempfile'
Time (mean ± σ): 59.8ms± 1.8ms[User: 54.2 ms, System: 5.5 ms]
Range (min … max): 57.4ms… 69.4ms50 runs

Benchmark 12: ./python -c 'import traceback'
Time (mean ± σ): 54.8ms± 1.0ms[User: 50.3 ms, System: 4.4 ms]
Range (min … max): 52.4ms… 56.9ms56 runs

Benchmark 13: ./python -c 'import urllib'
Time (mean ± σ): 29.5ms± 0.6ms[User: 26.2 ms, System: 3.1 ms]
Range (min … max): 28.3ms… 31.9ms100 runs

Benchmark 14: ./python -c 'import xml'
Time (mean ± σ): 29.7ms± 1.1ms[User: 26.7 ms, System: 3.0 ms]
Range (min … max): 28.2ms… 38.3ms102 runs

Warning: Statistical outliers were detected. Consider re-running this benchmark on a quiet system without any interferences from other programs. It might help to use the '--warmup' or '--prepare' options.

Summary
./python -c 'import zipimport' ran
1.05 ± 0.07 times faster than ./python -c 'import importlib'
1.08 ± 0.08 times faster than ./python -c 'import codeop'
1.19 ± 0.06 times faster than ./python -c 'import hmac'
1.21 ± 0.07 times faster than ./python -c 'import ctypes'
1.29 ± 0.06 times faster than ./python -c 'import urllib'
1.30 ± 0.07 times faster than ./python -c 'import xml'
2.40 ± 0.11 times faster than ./python -c 'import traceback'
2.58 ± 0.12 times faster than ./python -c 'import ssl'
2.58 ± 0.17 times faster than ./python -c 'import logging'
2.62 ± 0.14 times faster than ./python -c 'import tempfile'
2.68 ± 0.20 times faster than ./python -c 'import pkgutil'
3.45 ± 0.16 times faster than ./python -c 'import rlcompleter'
5.01 ± 0.26 times faster than ./python -c 'import pydoc'

First experiment in PR branch

➜ cpython git:(issue-118761) ✗ hyperfine --warmup 11 "./python -c 'import codeop'" "./python -c 'import zipimport'" "./python -c 'import ctypes'" "./python -c 'import hmac'" "./python -c 'import importlib'" "./python -c 'import logging'" "./python -c 'import pkgutil'" "./python -c 'import pydoc'" "./python -c 'import rlcompleter'" "./python -c 'import ssl'" "./python -c 'import tempfile'" "./python -c 'import traceback'" "./python -c 'import urllib'" "./python -c 'import xml'" Benchmark 1: ./python -c 'import codeop' Time (mean ± σ): 23.5 ms ± 1.0 ms [User: 21.0 ms, System: 2.5 ms] Range (min … max): 22.6 ms … 33.2 ms 121 runs 

Warning: Statistical outliers were detected. Consider re-running this benchmark on a quiet system without any interferences from other programs. It might helptouse the '--warmup'or'--prepare' options.

Benchmark2: ./python -c 'import zipimport'
Time (mean ± σ): 22.6 ms ± 0.8 ms [User: 20.3 ms, System: 2.2 ms]
Range (minmax): 21.6 ms … 29.5 ms 127 runs

Warning: Statistical outliers were detected. Consider re-running this benchmarkon a quiet systemwithoutany interferences from other programs. It might helptouse the '--warmup'or'--prepare' options.

Benchmark3: ./python -c 'import ctypes'
Time (mean ± σ): 27.3 ms ± 0.5 ms [User: 24.3 ms, System: 3.0 ms]
Range (minmax): 26.4 ms … 29.0 ms 107 runs

Benchmark4: ./python -c 'import hmac'
Time (mean ± σ): 26.2 ms ± 0.6 ms [User: 23.3 ms, System: 2.9 ms]
Range (minmax): 25.3 ms … 27.7 ms 108 runs

Benchmark5: ./python -c 'import importlib'
Time (mean ± σ): 22.9 ms ± 1.3 ms [User: 20.6 ms, System: 2.3 ms]
Range (minmax): 22.0 ms … 35.4 ms 125 runs

Warning: Statistical outliers were detected. Consider re-running this benchmarkon a quiet systemwithoutany interferences from other programs. It might helptouse the '--warmup'or'--prepare' options.

Benchmark6: ./python -c 'import logging'
Time (mean ± σ): 51.3 ms ± 0.8 ms [User: 47.3 ms, System: 3.9 ms]
Range (minmax): 49.8 ms … 53.7 ms 58 runs

Benchmark7: ./python -c 'import pkgutil'
Time (mean ± σ): 51.1 ms ± 0.8 ms [User: 47.3 ms, System: 3.8 ms]
Range (minmax): 49.5 ms … 53.6 ms 58 runs

Benchmark8: ./python -c 'import pydoc'
Time (mean ± σ): 85.8 ms ± 2.5 ms [User: 80.5 ms, System: 5.2 ms]
Range (minmax): 84.4 ms … 99.8 ms 35 runs

Warning: Statistical outliers were detected. Consider re-running this benchmarkon a quiet systemwithoutany interferences from other programs. It might helptouse the '--warmup'or'--prepare' options.

Benchmark9: ./python -c 'import rlcompleter'
Time (mean ± σ): 60.6 ms ± 0.8 ms [User: 55.8 ms, System: 4.6 ms]
Range (minmax): 59.2 ms … 63.9 ms 49 runs

Benchmark10: ./python -c 'import ssl'
Time (mean ± σ): 45.4 ms ± 1.7 ms [User: 41.3 ms, System: 4.0 ms]
Range (minmax): 43.9 ms … 58.1 ms 65 runs

Warning: Statistical outliers were detected. Consider re-running this benchmarkon a quiet systemwithoutany interferences from other programs. It might helptouse the '--warmup'or'--prepare' options.

Benchmark11: ./python -c 'import tempfile'
Time (mean ± σ): 46.1 ms ± 1.7 ms [User: 41.8 ms, System: 4.2 ms]
Range (minmax): 44.3 ms … 58.2 ms 65 runs

Warning: Statistical outliers were detected. Consider re-running this benchmarkon a quiet systemwithoutany interferences from other programs. It might helptouse the '--warmup'or'--prepare' options.

Benchmark12: ./python -c 'import traceback'
Time (mean ± σ): 42.4 ms ± 0.8 ms [User: 38.7 ms, System: 3.4 ms]
Range (minmax): 40.4 ms … 44.3 ms 70 runs

Benchmark13: ./python -c 'import urllib'
Time (mean ± σ): 22.9 ms ± 0.6 ms [User: 20.4 ms, System: 2.4 ms]
Range (minmax): 22.0 ms … 24.8 ms 122 runs

Benchmark14: ./python -c 'import xml'
Time (mean ± σ): 24.6 ms ± 1.4 ms [User: 22.1 ms, System: 2.4 ms]
Range (minmax): 22.2 ms … 33.0 ms 126 runs

Summary
./python -c 'import zipimport' ran
1.01 ± 0.04 times faster than ./python -c 'import urllib'
1.01 ± 0.07 times faster than ./python -c 'import importlib'
1.04 ± 0.06 times faster than ./python -c 'import codeop'
1.09 ± 0.07 times faster than ./python -c 'import xml'
1.16 ± 0.05 times faster than ./python -c 'import hmac'
1.21 ± 0.05 times faster than ./python -c 'import ctypes'
1.88 ± 0.07 times faster than ./python -c 'import traceback'
2.01 ± 0.10 times faster than ./python -c 'import ssl'
2.04 ± 0.10 times faster than ./python -c 'import tempfile'
2.26 ± 0.08 times faster than ./python -c 'import pkgutil'
2.27 ± 0.09 times faster than ./python -c 'import logging'
2.68 ± 0.10 times faster than ./python -c 'import rlcompleter'
3.80 ± 0.17 times faster than ./python -c 'import pydoc'

Second experiment in PR branch

➜ cpython git:(issue-118761) ✗ hyperfine --warmup 11"./python -c 'import codeop'""./python -c 'import zipimport'""./python -c 'import ctypes'""./python -c 'import hmac'""./python -c 'import importlib'""./python -c 'import logging'""./python -c 'import pkgutil'""./python -c 'import pydoc'""./python -c 'import rlcompleter'""./python -c 'import ssl'""./python -c 'import tempfile'""./python -c 'import traceback'""./python -c 'import urllib'""./python -c 'import xml'" Benchmark 1: ./python -c 'import codeop' Time (mean ± σ): 23.7ms± 1.0ms[User: 21.0 ms, System: 2.6 ms] Range (min … max): 22.7ms… 31.0ms122 runs 

Warning: Statistical outliers were detected. Consider re-running this benchmark on a quiet system without any interferences from other programs. It might help to use the '--warmup' or '--prepare' options.

Benchmark 2: ./python -c 'import zipimport'
Time (mean ± σ): 22.6ms± 0.5ms[User: 20.1 ms, System: 2.4 ms]
Range (min … max): 21.7ms… 24.0ms126 runs

Benchmark 3: ./python -c 'import ctypes'
Time (mean ± σ): 27.6ms± 0.5ms[User: 24.7 ms, System: 2.8 ms]
Range (min … max): 26.5ms… 28.9ms104 runs

Benchmark 4: ./python -c 'import hmac'
Time (mean ± σ): 26.5ms± 1.0ms[User: 23.2 ms, System: 3.2 ms]
Range (min … max): 25.4ms… 33.1ms111 runs

Benchmark 5: ./python -c 'import importlib'
Time (mean ± σ): 23.0ms± 0.7ms[User: 20.6 ms, System: 2.4 ms]
Range (min … max): 22.1ms… 25.5ms121 runs

Benchmark 6: ./python -c 'import logging'
Time (mean ± σ): 51.5ms± 0.9ms[User: 47.2 ms, System: 4.2 ms]
Range (min … max): 49.9ms… 54.6ms58 runs

Benchmark 7: ./python -c 'import pkgutil'
Time (mean ± σ): 51.9ms± 1.4ms[User: 47.8 ms, System: 4.0 ms]
Range (min … max): 49.7ms… 58.4ms57 runs

Benchmark 8: ./python -c 'import pydoc'
Time (mean ± σ): 88.1ms± 2.2ms[User: 82.1 ms, System: 5.8 ms]
Range (min … max): 85.1ms… 93.3ms34 runs

Benchmark 9: ./python -c 'import rlcompleter'
Time (mean ± σ): 63.6ms± 3.5ms[User: 58.6 ms, System: 4.9 ms]
Range (min … max): 59.4ms… 76.9ms38 runs

Benchmark 10: ./python -c 'import ssl'
Time (mean ± σ): 50.6ms± 1.5ms[User: 46.2 ms, System: 4.3 ms]
Range (min … max): 48.9ms… 60.0ms60 runs

Warning: Statistical outliers were detected. Consider re-running this benchmark on a quiet system without any interferences from other programs. It might help to use the '--warmup' or '--prepare' options.

Benchmark 11: ./python -c 'import tempfile'
Time (mean ± σ): 50.7ms± 0.8ms[User: 45.7 ms, System: 4.8 ms]
Range (min … max): 49.1ms… 53.1ms59 runs

Benchmark 12: ./python -c 'import traceback'
Time (mean ± σ): 54.3ms± 3.5ms[User: 49.3 ms, System: 4.9 ms]
Range (min … max): 46.8ms… 71.1ms63 runs

Benchmark 13: ./python -c 'import urllib'
Time (mean ± σ): 30.0ms± 0.6ms[User: 26.9 ms, System: 3.0 ms]
Range (min … max): 28.4ms… 32.0ms97 runs

Benchmark 14: ./python -c 'import xml'
Time (mean ± σ): 29.9ms± 0.7ms[User: 26.7 ms, System: 3.1 ms]
Range (min … max): 28.4ms… 32.1ms100 runs

Summary
./python -c 'import zipimport' ran
1.02 ± 0.04 times faster than ./python -c 'import importlib'
1.05 ± 0.05 times faster than ./python -c 'import codeop'
1.17 ± 0.05 times faster than ./python -c 'import hmac'
1.22 ± 0.04 times faster than ./python -c 'import ctypes'
1.32 ± 0.04 times faster than ./python -c 'import xml'
1.33 ± 0.04 times faster than ./python -c 'import urllib'
2.24 ± 0.08 times faster than ./python -c 'import ssl'
2.24 ± 0.06 times faster than ./python -c 'import tempfile'
2.28 ± 0.06 times faster than ./python -c 'import logging'
2.30 ± 0.08 times faster than ./python -c 'import pkgutil'
2.40 ± 0.16 times faster than ./python -c 'import traceback'
2.82 ± 0.17 times faster than ./python -c 'import rlcompleter'
3.90 ± 0.13 times faster than ./python -c 'import pydoc'

@donbarbosdonbarbos changed the title gh-118761: Improve import time of codeopgh-118761: Improve import time by lazy import of warningsFeb 7, 2025
@picnixz
Copy link
Member

Thanks for doing this. I did it for hmac locally since I'm implementing the HACL* hmac nut it's good to see it done here.

Copy link
Member

@picnixzpicnixz left a comment

Choose a reason for hiding this comment

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

Please revert the whitespaces and unrelated new lines changes (unless the codeowners tell you that you can keep the changes though)

@bedevere-app
Copy link

A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated.

Once you have made the requested changes, please leave a comment on this pull request containing the phrase I have made the requested changes; please review again. I will then notify any core developers who have left a review that you're ready for them to take another look at this pull request.

@AA-Turner
Copy link
Member

We should verify that each change has non-noise benefits rather than changing everything at once in an omnibus PR. @donbarbos also please present your motivating statistics in a more readable manner, I expect to see a comparison of each module against baseline, rather than four large log outputs.

A

@brettcannonbrettcannon requested review from brettcannon and removed request for brettcannonFebruary 12, 2025 22:07
@jaraco
Copy link
Member

I ran a test for importlib.resources, and this change if anything makes things worse:

 cpython issue-118761 🐚 hyperfine --warmup 11 "./python.exe -c 'import importlib.resources'" Benchmark 1: ./python.exe -c 'import importlib.resources' Time (mean ± σ): 26.6 ms ± 0.5 ms [User: 20.9 ms, System: 3.8 ms] Range (min … max): 25.4 ms … 28.7 ms 101 runs cpython issue-118761 [1] 🐚 git checkout @$(git merge-base HEAD main) HEAD is now at 0fef47e5bbd gh-55454: Add IMAP4 IDLE support to imaplib (#122542) cpython 0fef47e5bbd 🐚 hyperfine --warmup 11 "./python.exe -c 'import importlib.resources'" Benchmark 1: ./python.exe -c 'import importlib.resources' Time (mean ± σ): 25.9 ms ± 0.6 ms [User: 21.4 ms, System: 3.8 ms] Range (min … max): 24.8 ms … 27.6 ms 98 runs 

Sounds like we should revert those changes from this PR.

@AA-Turner
Copy link
Member

I'll close this PR as the contributor has opened some smaller individual changes.

A

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants

@donbarbos@picnixz@AA-Turner@jaraco@brettcannon@vsajip@Wulian233