| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
|
The PR: will probably drastically improve the speed as well as once string lazy imports re it will drastically speed up the string import and this module only uses the string module to import constants from string import ascii_letters, digits, hexdigits |
Sorry, something went wrong.
|
I did not notice that the warmup needed for ./python -X importtime -c 'import email.quoprimime' and so the more accurate timings are actually: regex: 153.9974 ± 35.97 (103 to 1778; n=10000)
non_regex: 148.4565 ± 25.48 (125 to 991; n=10000) |
Sorry, something went wrong.
|
( the new _HEX_TO_CHAR cache could also be used for the decode function as well afterwards since it checks for more or less the same thing) # Decode if in form =AB
elif i+2 < n and line[i+1] in hexdigits and line[i+2] in hexdigits:
decoded += unquote(line[i:i+3]) |
Sorry, something went wrong.
Slightly faster |
Sorry, something went wrong.
|
Adding the '=' check now speeds things up:
|
Sorry, something went wrong.
|
As a comparison (if you compile the regex for the function + add early exit) c = re.compile("=[a-fA-F0-9]{2}", flags=re.ASCII)
def header_decode_re(s):
"""Decode a string using regex."""
s = s.replace('_', ' ') # Replace underscores with spaces
if '=' in s:
return c.sub(_unquote_match, s)
return s
|
Sorry, something went wrong.
Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com>
|
@AA-Turner, what's your opinion on replacing this regex expression (even though it sometimes makes the algorithm slower)? |
Sorry, something went wrong.
|
Very slight improvement (mainly on the edge_case_short and short where string concatenation is faster than using "".join()
|
Sorry, something went wrong.
There was a problem hiding this comment.
This is slower and harder to maintain, so I'm -1 on this PR
Sorry, something went wrong.
|
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. |
Sorry, something went wrong.
|
Actually I don't understand this PR. It looks like we still import re transitively? Also I don't understand why the "self" time reported by -X importtime in your PR body goes from 1777 to 168, if anything looks like quoprimime.py does more work at import time now |
Sorry, something went wrong.
|
I'm a bit lost on the current benchmarks, but the most recent comment (with non_regex_add) appears to indicate this is slightly faster. That said, I agree with @hauntsaninja that the algorithm in the PR is too complicated and will be difficult to maintain, in contrast to the one-liner regular expression.
Through string, see #132037 to help there. A |
Sorry, something went wrong.
I agree this is odd. I've been using the below (rough) script to benchmark import times, for more data points than just a single run. bench.pyimport subprocess, sys
import statistics
BASE_CMD = (sys.executable, '-Ximporttime', '-S', '-c',)
def run_importtime(mod: str) -> str:
return subprocess.run(BASE_CMD + (f'import {mod}',), check=True, capture_output=True, encoding='utf-8').stderr
for mod in sys.argv[1:]:
for _ in range(5): # warmup
lines = run_importtime(mod)
print(lines.partition('\n')[0])
own_times = []
cum_times = []
for _ in range(50):
lines = run_importtime(mod)
final_line = lines.rstrip().rpartition('\n')[-1]
# print(final_line)
# import time: {own} | {cum} | {mod}
own, cum = map(int, final_line.split()[2:5:2])
own_times.append(own)
cum_times.append(cum)
own_times.sort()
cum_times.sort()
own_times[:] = own_times[10:-10]
cum_times[:] = cum_times[10:-10]
for label, times in [('own', own_times), ('cumulative', cum_times)]:
print()
print(f'import {mod}: {label} time')
print(f'mean: {statistics.mean(times):.3f} µs')
print(f'median: {statistics.median(times):.3f} µs')
print(f'stdev: {statistics.stdev(times):.3f}')
print('min:', min(times))
print('max:', max(times)) |
Sorry, something went wrong.
Sorry, something went wrong.
| if '=' not in s: | ||
| return s | ||
|
|
||
| result = '' |
There was a problem hiding this comment.
Repeatedly appending to a string in a loop is O(n**2). The standard idiom is to make a list of pieces (result=[]) and join after the loop. I suspect that re.sub does the C equivalent.
In any case, I agree that replacing an re call with this much code seems dubious (a bad tradeoff), so closing this might be best.
Sorry, something went wrong.
| Back | FazBrowse Home | New Git URL |
This pull request removes the re module from the email.quoprimime, thus increasing the import speed from 5676 us to 3669 us (a 60% import speed increase );
From
To
however, the new implementation does increase the compute time
So it is very possible that this is not worth it.
Issues: