-
Notifications
You must be signed in to change notification settings - Fork 67
decoder slowness when reading a zlib/zstd .NewReader() due to small .Read() buffers #635
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
here below is a copy of the test code https://go.dev/play/p/8eiq0ZpZLBG :
|
@folays Thanks for opening this issue and providing detailed information! I'll take a closer look (most likely next weekend). |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
cbor decoder is slow WHEN reading from a decompressor returning small buffers.
This seems to cause the cbor validation/
"wellformed"
code to do a lot of probably "restart" or something like that.When we interpose a "greedy" reader (
cbor decoder <- greedyReader <- decompressor
) its fast again.Go
's defaultjson.Unmarshal()
does not expose this behavior.(the tests below show that it is undisturbed by
io.Reader
returning lot of small.Read()
buffers)The aforementioned slowness occurs with :
compress/zlib
(andcompress/gzip
) //zlib
generally returns >= 31 kB.Read()
compress/lzw
github.com/klauspost/compress/zstd
//zstd
generally returns >= 493 kB.Read()
Albeit
zstd
is slightly less worse, becausezstd
'sReader
returns bigger.Read()
.Here below are 2 * 3 * 2 combination lines of tests bench :
.Read()
)The tests encode/decode an approximate of
map[128]*struct { map[128*1024]int }
,so roughly 256 MB of Go memory data, translating to (uncompressed) 239 MBs of JSON / 134 MBs of CBOR.
All tests takes 1-3s, except in the degenerate case of CBOR+decompression-reader,
which takes 24s with
zstd
, and 357s withzlib
(on a 7950X CPU single thread). (Go 1.24)Be cautious of not running it in "debug" mode or whatnot, I observed that in
GoLand
it would run a lot slower in "Debug" than in "Run".Above code is here https://go.dev/play/p/8eiq0ZpZLBG but I will add a comment with the code.
A
Go
CPU profile run showed me that 99% of time is passed insidecbor.(*decoder).wellformedinternal
.The text was updated successfully, but these errors were encountered: