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

blob: pass through reader/writer to WriteTo/ReadFrom if available #3267

Merged
merged 1 commit into from
Jun 27, 2023

Conversation

HippoBaro
Copy link
Contributor

The blob Reader and Writer implement WriterTo and ReaderFrom, respectively, which is meant to avoid intermediary allocations and copies (passing readers and readers through all the way down). Unfortunately, the current implementation falls short and implements those interfaces by making a local copy ala io.Copy.

Instead, reproduce the strategy in newer versions of io.Copy: reflect on the reader/writer provided by the user, and if they implement these interface, too, then call into that.

Local benchmarks show significant performance improvements:

                         │   /tmp/old   │              /tmp/new               │
                         │    sec/op    │   sec/op     vs base                │
Memblob/BenchmarkRead-10   3.449µ ± 15%   1.919µ ± 2%  -44.37% (p=0.000 n=10)

Most benchmarks use ReadAll and WriteAll, which use slices directly and don't benefit from this change. I modified the BenchmarkRead to use a bytes.Buffer and a call to io.Copy to exercise the WriteTo path. I believe we should change the remaining benchmarks to do the same. I don't think ReadAll/WriteAll represent how most real-world applications interact with the library (piping readers/writer instead, but that assumption may be wrong!)

The benchmark comparison above is fair; only the call to WriteTo was removed

The blob `Reader` and `Writer` implement `WriterTo` and `ReaderFrom`,
respectively, which is meant to avoid intermediary allocations and
copies (passing readers and readers through all the way down).
Unfortunately, the current implementation falls short and implements
those interfaces by making a local copy ala io.Copy.

Instead, reproduce the strategy in newer versions of `io.Copy`: reflect
on the reader/writer provided by the user, and if they implement these
interface, too, then call into that.

Local benchmarks show significant performance improvements:

```
                         │   /tmp/old   │              /tmp/new               │
                         │    sec/op    │   sec/op     vs base                │
Memblob/BenchmarkRead-10   3.449µ ± 15%   1.919µ ± 2%  -44.37% (p=0.000 n=10)
```
@google-cla
Copy link

google-cla bot commented Jun 27, 2023

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@codecov
Copy link

codecov bot commented Jun 27, 2023

Codecov Report

Merging #3267 (d83b0f6) into master (adb7ff5) will decrease coverage by 0.06%.
The diff coverage is 100.00%.

@@            Coverage Diff             @@
##           master    #3267      +/-   ##
==========================================
- Coverage   77.47%   77.42%   -0.06%     
==========================================
  Files         103      103              
  Lines       13603    13607       +4     
==========================================
- Hits        10539    10535       -4     
- Misses       2333     2340       +7     
- Partials      731      732       +1     
Impacted Files Coverage Δ
blob/blob.go 86.85% <100.00%> (-0.26%) ⬇️

... and 3 files with indirect coverage changes

@vangent vangent merged commit 8385fc3 into google:master Jun 27, 2023
6 checks passed
@HippoBaro HippoBaro deleted the hippobaro/passthrough_io branch June 27, 2023 19:15
ybourgery pushed a commit to Simprints/go-cloud that referenced this pull request Jun 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants