Repository navigation
Conversation
Backport of https://go.dev/cl/829570 (golang/go#81398). When estimating the gain of a candidate match at level 9, findMatch summed the literal code lengths of the whole match for every candidate that was longer than the best so far, which cost about a tenth of the encoding time. Compute a cumulative literal cost array over the window once per deflateLazy call, right after the literal encoder used for the estimate is generated, so that the cost of any range is a subtraction. Also hoist the hash chain fields into locals for the chain walk. Unlike upstream, litBits is a lazily allocated slice rather than an array in advancedState, so only level 9 writers pay the 256KB; levels 7 and 8 never generate the estimate tables. findMatch took the gain path for d.chain >= 100 while deflateLazy only generated the tables it needs for d.chain > 100. No level has a chain of exactly 100 so this was unreachable, but the mismatch is now load bearing (a nil litBits instead of a nil d.h), so the conditions are made to agree. bitLengthRaw is no longer used and is removed. The output is byte-identical. ``` goos: windows goarch: amd64 pkg: github.com/klauspost/compress/flate cpu: AMD Ryzen 9 9950X 16-Core Processor β master β cl-829570 β β sec/op β sec/op vs base β PR/Digits/Huffman-32 804.3Β΅ Β± 1% 801.7Β΅ Β± 1% ~ (p=0.305 n=15) PR/Digits/L1-32 4.731m Β± 1% 4.716m Β± 1% ~ (p=0.683 n=15) PR/Digits/L4-32 5.518m Β± 2% 5.486m Β± 2% ~ (p=0.285 n=15) PR/Digits/L6-32 7.879m Β± 5% 7.875m Β± 1% ~ (p=0.267 n=15) PR/Digits/L7-32 14.54m Β± 3% 14.50m Β± 1% ~ (p=0.116 n=15) PR/Digits/L9-32 32.37m Β± 3% 26.79m Β± 6% -17.23% (p=0.000 n=15) PR/Twain/Huffman-32 1.051m Β± 3% 1.051m Β± 2% ~ (p=0.775 n=15) PR/Twain/L1-32 4.726m Β± 2% 4.757m Β± 1% ~ (p=0.595 n=15) PR/Twain/L4-32 5.944m Β± 1% 5.898m Β± 1% ~ (p=0.187 n=15) PR/Twain/L6-32 7.773m Β± 3% 7.832m Β± 2% ~ (p=0.267 n=15) PR/Twain/L7-32 17.70m Β± 2% 17.50m Β± 1% ~ (p=0.202 n=15) PR/Twain/L9-32 36.68m Β± 1% 34.58m Β± 2% -5.72% (p=0.000 n=15) geomean 6.898m 6.745m -2.21% β B/s β B/s vs base β PR/Digits/Huffman-32 1.158Gi Β± 1% 1.162Gi Β± 1% ~ (p=0.305 n=15) PR/Digits/L1-32 201.6Mi Β± 1% 202.2Mi Β± 1% ~ (p=0.683 n=15) PR/Digits/L4-32 172.8Mi Β± 2% 173.8Mi Β± 2% ~ (p=0.281 n=15) PR/Digits/L6-32 121.0Mi Β± 5% 121.1Mi Β± 1% ~ (p=0.263 n=15) PR/Digits/L7-32 65.58Mi Β± 3% 65.76Mi Β± 1% ~ (p=0.116 n=15) PR/Digits/L9-32 29.47Mi Β± 3% 35.60Mi Β± 5% +20.81% (p=0.000 n=15) PR/Twain/Huffman-32 907.7Mi Β± 3% 907.3Mi Β± 2% ~ (p=0.775 n=15) PR/Twain/L1-32 201.8Mi Β± 2% 200.5Mi Β± 1% ~ (p=0.602 n=15) PR/Twain/L4-32 160.4Mi Β± 1% 161.7Mi Β± 1% ~ (p=0.187 n=15) PR/Twain/L6-32 122.7Mi Β± 3% 121.8Mi Β± 2% ~ (p=0.267 n=15) PR/Twain/L7-32 53.87Mi Β± 2% 54.49Mi Β± 1% ~ (p=0.202 n=15) PR/Twain/L9-32 26.00Mi Β± 1% 27.57Mi Β± 2% +6.05% (p=0.000 n=15) geomean 138.3Mi 141.4Mi +2.26% ``` Original-Author: Alex Gaynor <alex.gaynor@gmail.com> Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. π βΉοΈ Recent review infoβοΈ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Advanced Run ID: π Files selected for processing (2)
π€ Files with no reviewable changes (1)
Included review availability: Your plan provides up to 8 included reviews per hour; 4 remain after this review. π WalkthroughWalkthroughThe advanced deflate path now caches cumulative literal Huffman costs. ChangesDeflate gain estimation
Priority: β¬οΈ Low Estimated code review effort: 3 (Moderate) | ~20 minutes Change: Refactor Merge Risk: βͺ Minimal Β· up to The optimization preserves the established deflate gain-estimation contract without an identified correctness, stability, or output-compatibility regression. π₯ Pre-merge checks | β 5β Passed checks (5 passed)
β¨ Finishing Touchesπ Generate docstrings
π§ͺ Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Backport of https://go.dev/cl/829570 (golang/go#81398).
When estimating the gain of a candidate match at level 9, findMatch summed the literal code lengths of the whole match for every candidate that was longer than the best so far, which cost about a tenth of the encoding time.
Compute a cumulative literal cost array over the window once per deflateLazy call, right after the literal encoder used for the estimate is generated, so that the cost of any range is a subtraction. Also hoist the hash chain fields into locals for the chain walk.
Unlike upstream, litBits is a lazily allocated slice rather than an array in advancedState, so only level 9 writers pay the 256KB; levels 7 and 8 never generate the estimate tables.
findMatch took the gain path for d.chain >= 100 while deflateLazy only generated the tables it needs for d.chain > 100. No level has a chain of exactly 100 so this was unreachable, but the mismatch is now load bearing (a nil litBits instead of a nil d.h), so the conditions are made to agree.
bitLengthRaw is no longer used and is removed. The output is byte-identical.
Original-Author: Alex Gaynor alex.gaynor@gmail.com
Summary by CodeRabbit