Skip to content

Commit b3140ce

Browse files
authored
flate: Improve speed in big stateless blocks. (#718)
* flate: Improve speed in big stateless blocks. Don't re-alloc and copy dict for every block when compressing more than 32KB. ``` benchmark old ns/op new ns/op delta BenchmarkEncodeDigitsSL1e4-32 52954 52850 -0.20% BenchmarkEncodeDigitsSL1e5-32 781061 745420 -4.56% BenchmarkEncodeDigitsSL1e6-32 8143640 7715674 -5.26% BenchmarkEncodeTwainSL1e4-32 68150 68415 +0.39% BenchmarkEncodeTwainSL1e5-32 715140 687326 -3.89% BenchmarkEncodeTwainSL1e6-32 7718175 7339694 -4.90% benchmark old MB/s new MB/s speedup BenchmarkEncodeDigitsSL1e4-32 188.84 189.21 1.00x BenchmarkEncodeDigitsSL1e5-32 128.03 134.15 1.05x BenchmarkEncodeDigitsSL1e6-32 122.80 129.61 1.06x BenchmarkEncodeTwainSL1e4-32 146.74 146.17 1.00x BenchmarkEncodeTwainSL1e5-32 139.83 145.49 1.04x BenchmarkEncodeTwainSL1e6-32 129.56 136.25 1.05x benchmark old allocs new allocs delta BenchmarkEncodeDigitsSL1e4-32 0 0 +0.00% BenchmarkEncodeDigitsSL1e5-32 3 0 -100.00% BenchmarkEncodeDigitsSL1e6-32 41 0 -100.00% BenchmarkEncodeTwainSL1e4-32 0 0 +0.00% BenchmarkEncodeTwainSL1e5-32 3 0 -100.00% BenchmarkEncodeTwainSL1e6-32 41 0 -100.00% benchmark old bytes new bytes delta BenchmarkEncodeDigitsSL1e4-32 0 0 +0.00% BenchmarkEncodeDigitsSL1e5-32 92929 9 -99.99% BenchmarkEncodeDigitsSL1e6-32 1298964 97 -99.99% BenchmarkEncodeTwainSL1e4-32 0 0 +0.00% BenchmarkEncodeTwainSL1e5-32 92928 8 -99.99% BenchmarkEncodeTwainSL1e6-32 1298871 92 -99.99% ``` * Pin garble to v0.7.2
1 parent 1f355e8 commit b3140ce

File tree

4 files changed

+19
-6
lines changed

4 files changed

+19
-6
lines changed

.github/workflows/go.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ jobs:
8585
run: go build github.com/klauspost/compress/s2/cmd/s2c && go build github.com/klauspost/compress/s2/cmd/s2d&&./s2c -verify s2c &&./s2d s2c.s2&&rm ./s2c&&rm s2d&&rm s2c.s2
8686

8787
- name: install garble
88-
run: go install mvdan.cc/[email protected].0
88+
run: go install mvdan.cc/[email protected].2
8989

9090
- name: goreleaser deprecation
9191
run: curl -sfL https://git.io/goreleaser | VERSION=v1.9.2 sh -s -- check

.github/workflows/release.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ jobs:
2121
go-version: 1.19.x
2222
-
2323
name: install garble
24-
run: go install mvdan.cc/[email protected].1
24+
run: go install mvdan.cc/[email protected].2
2525
-
2626
name: Run GoReleaser
2727
uses: goreleaser/goreleaser-action@v2

.goreleaser.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
before:
44
hooks:
55
- ./gen.sh
6-
- go install mvdan.cc/garble@latest
6+
- go install mvdan.cc/garble@v0.7.2
77

88
builds:
99
-

flate/stateless.go

+16-3
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,19 @@ func StatelessDeflate(out io.Writer, in []byte, eof bool, dict []byte) error {
8686
dict = dict[len(dict)-maxStatelessDict:]
8787
}
8888

89+
// For subsequent loops, keep shallow dict reference to avoid alloc+copy.
90+
var inDict []byte
91+
8992
for len(in) > 0 {
9093
todo := in
91-
if len(todo) > maxStatelessBlock-len(dict) {
94+
if len(inDict) > 0 {
95+
if len(todo) > maxStatelessBlock-maxStatelessDict {
96+
todo = todo[:maxStatelessBlock-maxStatelessDict]
97+
}
98+
} else if len(todo) > maxStatelessBlock-len(dict) {
9299
todo = todo[:maxStatelessBlock-len(dict)]
93100
}
101+
inOrg := in
94102
in = in[len(todo):]
95103
uncompressed := todo
96104
if len(dict) > 0 {
@@ -102,7 +110,11 @@ func StatelessDeflate(out io.Writer, in []byte, eof bool, dict []byte) error {
102110
todo = combined
103111
}
104112
// Compress
105-
statelessEnc(&dst, todo, int16(len(dict)))
113+
if len(inDict) == 0 {
114+
statelessEnc(&dst, todo, int16(len(dict)))
115+
} else {
116+
statelessEnc(&dst, inDict[:maxStatelessDict+len(todo)], maxStatelessDict)
117+
}
106118
isEof := eof && len(in) == 0
107119

108120
if dst.n == 0 {
@@ -119,7 +131,8 @@ func StatelessDeflate(out io.Writer, in []byte, eof bool, dict []byte) error {
119131
}
120132
if len(in) > 0 {
121133
// Retain a dict if we have more
122-
dict = todo[len(todo)-maxStatelessDict:]
134+
inDict = inOrg[len(uncompressed)-maxStatelessDict:]
135+
dict = nil
123136
dst.Reset()
124137
}
125138
if bw.err != nil {

0 commit comments

Comments
 (0)