-
Notifications
You must be signed in to change notification settings - Fork 17.7k
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
proposal: io: default ByteReader from Reader #37344
Comments
Reading one byte at a time without caching would be extremely slow for any real io, just something to consider. |
As you show, you can already do this yourself. So the only question is whether this should be in the standard library. Is this really something that comes up often enough to add to the standard library? https://golang.org/doc/faq#x_in_std |
@OneOfOne yes that is true, hence why it falls back to the underlying Reader implementation of ByteReader if it exists. @ianlancetaylor indeed. And I filed this proposal after thinking about this and coming to the conclusion that this could go with the ioutil.NopCloser, which I do use from time to time as it is convenient albeit not too often. Such would be the case for the ByteReader. Not sure how this comes up in practice outside of the standard library, I havent investigated this yet. I could if this helps. |
It's not clear to me that external package keep repeating the creation of an |
The reason that io.ByteReader exists at all is that some code wants to read one byte at a time, and that really can't be done well without an underlying larger buffer. That is, Read of 1-byte slices is so suboptimal to be worth defining this added interface. This is why Uvarint takes an io.ByteReader in the first place instead of an io.Reader. Having a "default" implementation that converts io.Reader to io.ByteReader by making 1-byte reads is going to have all the slowness we were avoiding by not doing that in the implementations. In general having a ReadByte method is an assertion "I have an efficient way to read 1 byte at a time". This would not be making that claim accurately. We could document this better in the io.ByteReader docs. The right answer for your case is to add a buffer, likely using bytes.Buffer, as high up in the call stack as possible, so that the buffer is amortized across as many calls as possible. |
@rsc thank you it makes sense.
|
Change https://golang.org/cl/221380 mentions this issue: |
As @robpike says on CL 221380:
|
@robpike said he would take a stab at a CL for wording an appropriate comment. |
Based on the discussion above, however, the proposal to add a helper wrapper that does 1-byte reads seems like a likely decline. |
Change https://golang.org/cl/223097 mentions this issue: |
Offered as an alternative to CL 221380, which was more tutorial than necessary. Update #37344 Change-Id: Ide673b0b97983c2c2319a9311dc3d0a10567e6c4 Reviewed-on: https://go-review.googlesource.com/c/go/+/223097 Reviewed-by: Ian Lance Taylor <iant@golang.org>
No change in consensus, and Rob's CL landed, so declining. |
Background & Motivation
When using some APIs such as ReadUvarint, sometimes the need arise to provide an io.ByteReader when only an io.Reader is available. Currently, there are 2 main ways this is addressed:
The downsides of the current solutions are:
A quick look at the standard library shows that the second option is usually the preferred method:
compress/bzip2
compress/flate
compress/lzw
encoding/xml
image/gif
Goals
Simplify usage of APIs requiring io.ByteReader's.
Reduce memory footprint when needing an io.ByteReader from an io.Reader.
Design
Provide a new type that implements the wrapper. Something like below.
To be decided
The package where this type would live: io, ioutil other?
Backwards Compatibility
This proposal is backward compatible.
The text was updated successfully, but these errors were encountered: