| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
|
This PR is stale because it has been open for 30 days with no activity. |
Sorry, something went wrong.
There was a problem hiding this comment.
Try to use a bytearray instead of io.BytesIO. Would it be faster? In what cases?
Sorry, something went wrong.
There was a problem hiding this comment.
Performance improvement was necessary (see bug report). So I made it better the following way:
This means for the most common use cases (no flags or only FNAME set) that only a few extra truthy checks are performed. This comes at a very low cost of 3% (see the bug report for results).
This is worth it since it enables correct truncation checking for FNAME and FCOMMENT as well as enabling checking of the header CRC when FHCRC is set.
Sorry, something went wrong.
|
@serhiy-storchaka Thank you for taking a look and thank you for your insights. I have updated the PR accordingly. It is much better now in terms of performance. |
Sorry, something went wrong.
Call the bool method and cache the result for faster truth checking. Do not test for empty bytes but use "not magic" instead for faster truth checking.
|
I made a small tweek that shaves off another 2 microseconds
|
Sorry, something went wrong.
Those are: + Only FNAME set. (Created by gzip and python's GzipFile) + No flags set. (Created by gzip.compress and zlib.compress with wbits=31)
|
With further performance tweaks, reading the gzip header is now either faster or neutral compared to the most common flags (no flags, or only FNAME set). See bpo-45509 for more performance details. The performance tweaks are:
|
Sorry, something went wrong.
|
@serhiy-storchaka The PR is ready for re-review when you have the time. The performance issue has been addressed. |
Sorry, something went wrong.
Sorry, something went wrong.
|
This PR is stale because it has been open for 30 days with no activity. |
Sorry, something went wrong.
|
I got a message that this branch is stale. So I rechecked the code again. It's been a few years. I think it comes down whether CPython wants to comply to RFC1952 or not. This PR makes the header parsing spec compliant. In practice header CRCs are mostly not used. So the other angle is to argue that having less code to maintain is more important than to the letter spec compliance. My view on this is that this code can live untouched for decades to come (just like the old code was left untouched for at least a decade). So I'd be inclined to merge it. |
Sorry, something went wrong.
Remove double import of zlib
There was a problem hiding this comment.
Thank you for your patience @rhpvorderman. I am not very happy that the code becomes more complicated, but checking the CRC of the header if it is provided is the right thing. You have made considerable efforts to minimize the cost. I am inclined to accept this PR.
Yet one question. Did you consider to use a bytearray instead of a list to accumulate the header data?
Sorry, something went wrong.
|
Hi. Thank you for your suggestions. I have factored out the reading until NULL to make the code more simple and use a bytearray as suggested. This means there is a small increase in cost when only the FNAME flag is set, but the code is simpler. Technically that code could also be replaced with the original code for less simplicity but more speed. With these changes I think the number of extra lines are minimized (+23) and readability is hopefully not aversely affected. |
Sorry, something went wrong.
|
|
||
| def _read_until_null(fp): | ||
| '''Read until the first encountered null byte in fp''' | ||
| result = io.BytesIO() |
There was a problem hiding this comment.
What if pass the bytearray buffer as argument to _read_until_null()? Would not it be faster?
Sorry, something went wrong.
There was a problem hiding this comment.
Yes. That makes more sense since it is a one-off function.
Sorry, something went wrong.
|
Okay I fiddled a bit with it. Should be as close to optimal now as possible. If no flags or if flag==FNAME the function exits early and with minimal investment. If people get really stressed out about the performance, they should probably be using python-zlib-ng and python-isal anyway. There this whole machinery is written in C. |
Sorry, something went wrong.
|
Thanks for reviewing and providing feedback. It is always a nice learning opportunity to contribute back to CPython! I did check the BytesIO and Bytearray code to see what would be more costly, but they use the same memory amortization techniques so it probably does not matter. I did find the += of bytearray to be more visually appealing so I opted for that as you suggested. In python-isal and python-zlib-ng I use a sort of buffered structure where the whole header is in the buffer already. The CRC check is just checking the buffer a few bytes back rather than having to save everything in a separate object. That only works by virtue of it being written in C though, so not really viable here. |
Sorry, something went wrong.
|
Thanks @rhpvorderman for the PR, and @serhiy-storchaka for merging it 🌮🎉.. I'm working now to backport this PR to: 3.15. |
Sorry, something went wrong.
|
GH-149769 is a backport of this pull request to the 3.15 branch. |
Sorry, something went wrong.
| Back | FazBrowse Home | New Git URL |
Check whether the COMMENT, NAME and HCRC fields are correct.
EDIT: Additionally, slightly increase performance for header checking for headers produced by gzip.compress or zlib.compress.
https://bugs.python.org/issue45509