Skip to content
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

lz4 decompression causes a lot of allocations due to ioutil.ReadAll #623

Closed
kalbhor opened this issue Nov 23, 2023 · 7 comments · Fixed by #629
Closed

lz4 decompression causes a lot of allocations due to ioutil.ReadAll #623

kalbhor opened this issue Nov 23, 2023 · 7 comments · Fixed by #629
Labels
enhancement New feature or request help wanted

Comments

@kalbhor
Copy link

kalbhor commented Nov 23, 2023

While using a consumer group where messages were lz4 compressed I noticed most of the allocations were due to ioutil.ReadAll. Should we consider using io.Copy (fixed buffer length) instead of ioutil.ReadAll (dynamically resized array)? I can provide benchmark results if needed

@twmb
Copy link
Owner

twmb commented Nov 27, 2023

What does code look like that avoids ReadAll? io.Copy requires a destination to read into, and I don't think we can know the size of what the blob will decompress into ahead of time.

@kalbhor
Copy link
Author

kalbhor commented Nov 28, 2023

Since we don't know the final buffer size, we can't pre-allocate. But it looks like bytes.Buffer has a more optimal grow buffer method for most cases. Since ReadAll depends on append's grow strategy, it is generally discouraged for reading large data in-memory. There are discussions around this : golang/go#50774

I used such an io.Copy example for benchmarks:

func decompressCopy(d []byte) ([]byte, error) {
	dc := dcPool.Get().(*lz4.Reader)
	defer dcPool.Put(dc)
	dc.Reset(bytes.NewReader(d))

	out := new(bytes.Buffer)
	if _, err := io.Copy(out, dc); err != nil {
		return nil, err
	}

	return out.Bytes(), nil
}

@twmb
Copy link
Owner

twmb commented Dec 1, 2023

Sure, makes sense 👍

@kalbhor
Copy link
Author

kalbhor commented Dec 2, 2023

I found that gzip decompress also uses ioutil.ReadAll and could in most cases benefit from a bytes.Buffer. If you like I can open a pull request with these changes

@twmb
Copy link
Owner

twmb commented Dec 3, 2023

Sure, also good. +1 to PR

@twmb twmb added enhancement New feature or request help wanted labels Dec 3, 2023
@twmb
Copy link
Owner

twmb commented Dec 3, 2023

Let me know if you can get a PR open in the next day or two -- I have two other PRs ready that can go into a patch release and this can fit as well.

@kalbhor
Copy link
Author

kalbhor commented Dec 4, 2023

Replaced ReadAll with bytes buffer for gzip and lz4 decompression

@twmb twmb closed this as completed in #629 Dec 6, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants