-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
quicvarint: add Reader and Writer interfaces #3233
Conversation
Read doesn’t currently use io.Reader interface. This was done for symmetry.
Thank you for this PR. |
Codecov Report
@@ Coverage Diff @@
## master #3233 +/- ##
==========================================
- Coverage 85.46% 85.44% -0.01%
==========================================
Files 133 134 +1
Lines 9799 9811 +12
==========================================
+ Hits 8374 8383 +9
- Misses 1052 1053 +1
- Partials 373 375 +2
Continue to review full report at Codecov.
|
When I ran the existing benchmarks suite, it seemed on par. I can add benchmarks for If the type assertion does negatively impact the benchmarks, what do you think about changing the method signatures to accept a |
Our benchmark package is a few years old and frankly, it's not very useful any more. I was thinking of a microbenchmark just for the
I wouldn't be opposed to that. I assume it doesn't break any (quic-go) code, does it? |
Sounds good. Would you prefer a gomega/ginkgo or vanilla Go benchmark?
It didn’t, since every existing caller passes a |
- Read(io.Reader) with type assertion to quicvarint.Reader - Read(io.ByteReader) with no type assertion (current master branch) - Read(quicvarint.Reader) with no type assertion Results: the current Read func in this branch is approximately 86% slower (1.86x) runtime than Read on current master branch. The other implementation which accepts a quicvarint.Reader with no type assertion is on par with master. Given this function is in the hot path, I recommend we eliminate the type assertion in favor of the caller ensuring argument to Read() satisfies the quicvarint.Reader or io.ByteReader interface.
@marten-seemann looks like you’re right. The type assertion exacts a material penalty in the ❯ go test -bench . ./quicvarint
Running Suite: QUIC Varint Suite
================================
Random Seed: 1626839707
Will run 40 of 40 specs
••••••••••••••••••••••••••••••
------------------------------
• [MEASUREMENT]
Benchmarks
with type assertion to quicvarint.Reader
reading from a bytes.Reader
Ran 100 samples:
read:
Fastest Time: 0.000s
Slowest Time: 0.000s
Average Time: 0.000s ± 0.000s
read one (ns):
Smallest: 17.913
Largest: 64.634
Average: 21.401 ± 5.843
read all (ns):
Smallest: 5732.000
Largest: 20683.000
Average: 6848.420 ± 1869.883
------------------------------
• [MEASUREMENT]
Benchmarks
old Read(io.ByteReader) without type assertion
reading from a bytes.Reader
Ran 100 samples:
read:
Fastest Time: 0.000s
Slowest Time: 0.000s
Average Time: 0.000s ± 0.000s
read one (ns):
Smallest: 10.466
Largest: 20.159
Average: 11.693 ± 1.975
read all (ns):
Smallest: 3349.000
Largest: 6451.000
Average: 3741.860 ± 631.840
------------------------------
• [MEASUREMENT]
Benchmarks
new Read(Reader) without type assertion
reading from a bytes.Reader
Ran 100 samples:
read:
Fastest Time: 0.000s
Slowest Time: 0.000s
Average Time: 0.000s ± 0.000s
read one (ns):
Smallest: 10.637
Largest: 63.631
Average: 11.613 ± 5.237
read all (ns):
Smallest: 3404.000
Largest: 20362.000
Average: 3716.000 ± 1675.817
------------------------------
••••••
Ran 40 of 40 Specs in 0.010 seconds
SUCCESS! -- 39 Passed | 0 Failed | 0 Pending | 0 Skipped
PASS
ok github.com/lucas-clemente/quic-go/quicvarint 0.145s |
Type algebra says that if r (type io.Reader) implements io.Reader and io.ByteReader, it implements Reader. Therefore the reader and writer structs are not needed, and can be eliminated.
This improves performance per call of Read by ~46% TODO: change parseNextFrame to accept quicvarint.Reader
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the benchmarks!
I have to admit I'm a bit confused now about the interfaces changes, see my comments on the code.
Unrelated: do you plan to remove the CircleCI and Travis checks? |
@marten-seemann I put up a PR (#3238) that builds on this PR. Do you want to review or merge this one? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One small comment, then this should be good to merge.
Can you please remove the benchmark file? Ginkgo has deprecated the benchmark functionality anyway.
Done. This was my first time using Ginkgo. I normally write vanilla Go tests. What drove the decision to use it? |
This PR adds two interfaces to the
quicvarint
package:Reader
andWriter
, that areio.Reader
+io.ByteReader
, andio.Writer
+io.ByteWriter
, respectively, along with constructors that pass through the argument unchanged if it implements the necessary interfaces.The interfaces to
quicvarint.Read
andWrite
are changed to accept aReader
andWriter
, respectively. This change didn’t break tests in any package in this repo, nor require any changes in any package that depends onquicvarint
.Why? This is a small bit of support work for #3226, to ease construction of a package that processes H3 streams and datagrams outside of the
http3
package.This PR also removes the existing
http3.byteReaderImpl
type, replacing it withquicvarint.Reader
.