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

Let io::copy reuse BufWriter buffers #78641

Merged
merged 1 commit into from
Feb 1, 2021
Merged

Conversation

the8472
Copy link
Member

@the8472 the8472 commented Nov 1, 2020

This optimization will allow users to implicitly set the buffer size for io::copy by wrapping the writer into a BufWriter if the default block size is insufficient, which should fix #49921

Due to min_specialization limitations this approach only works with BufWriter but not for BufReader<R> since R is unconstrained and thus the necessary specialization on R: Read is not always applicable. Once specialization becomes more powerful this optimization could be extended to look at the reader and writer side and use whichever buffer is larger.

@rust-highfive
Copy link
Collaborator

r? @shepmaster

(rust_highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Nov 1, 2020
library/std/src/io/copy.rs Outdated Show resolved Hide resolved
@jyn514 jyn514 added the T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. label Nov 1, 2020
@the8472 the8472 marked this pull request as draft November 13, 2020 20:09
@bors
Copy link
Contributor

bors commented Nov 14, 2020

☔ The latest upstream changes (presumably #75272) made this pull request unmergeable. Please resolve the merge conflicts.

Note that reviewers usually do not review pull requests until merge conflicts are resolved! Once you resolve the conflicts, you should change the labels applied by bors to indicate that your PR is ready for review. Post this as a comment to change the labels:

@rustbot modify labels: +S-waiting-on-review -S-waiting-on-author

@shepmaster shepmaster added S-blocked Status: Blocked on something else such as an RFC or other implementation work. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Nov 17, 2020
@the8472 the8472 marked this pull request as ready for review November 17, 2020 19:02
@the8472

This comment has been minimized.

@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Nov 17, 2020
@the8472
Copy link
Member Author

the8472 commented Nov 18, 2020

The resulting code feels a bit gnarly but I didn't want to duplicate the read-write loop because it contains all that unsafe code around uninitialized memory.

If it's accaptable to duplicate that code then the generic and the BufWriter-specific version could individually be made cleaner.

@the8472

This comment has been minimized.

@rustbot rustbot removed the S-blocked Status: Blocked on something else such as an RFC or other implementation work. label Nov 26, 2020
@the8472 the8472 mentioned this pull request Dec 11, 2020
@the8472
Copy link
Member Author

the8472 commented Dec 12, 2020

I'll hold off fixing the nits until I get a higher-level review.

@the8472

This comment has been minimized.

@shepmaster
Copy link
Member

I'ven't been able to give this the time it deserves.

r? @sfackler

@rust-highfive rust-highfive assigned sfackler and unassigned shepmaster Jan 1, 2021
@@ -56,12 +56,47 @@ where

/// The general read-write-loop implementation of
/// `io::copy` that is used when specializations are not available or not applicable.
pub(crate) fn generic_copy<R: ?Sized, W: ?Sized>(reader: &mut R, writer: &mut W) -> io::Result<u64>
pub(crate) fn generic_copy<R: ?Sized, W: ?Sized>(reader: &mut R, writer: &mut W) -> Result<u64>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems strange for there to be specialization in the function used "when specializations are not available or not applicable".

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That refers to another set of specializations. I'll try to reword it.

library/std/src/io/copy.rs Outdated Show resolved Hide resolved
library/std/src/io/copy.rs Outdated Show resolved Hide resolved
@sfackler
Copy link
Member

sfackler commented Feb 1, 2021

This looks good, thanks!

@bors r+

@bors
Copy link
Contributor

bors commented Feb 1, 2021

📌 Commit 4105506 has been approved by sfackler

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Feb 1, 2021
// Safety: The initializer contract guarantees that either it or `read`
// will have initialized these bytes. And we just checked that the number
// of bytes is within the buffer capacity.
unsafe { buf.set_len(buf.len() + bytes_read) };
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Huh, is std being built with polonious?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure what is causing surprise here. The x.foo(x.bar())? Isn't that just two-phase borrows?

@bors
Copy link
Contributor

bors commented Feb 1, 2021

⌛ Testing commit 4105506 with merge 8bd506e0f39d10dcc588ae469c9c6c73d0c568c6...

@bors
Copy link
Contributor

bors commented Feb 1, 2021

💥 Test timed out

@bors bors added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Feb 1, 2021
@bjorn3
Copy link
Member

bjorn3 commented Feb 1, 2021

The macOS builder is still running and showing new logs.

@rust-log-analyzer
Copy link
Collaborator

A job failed! Check out the build log: (web) (plain)

Click to see the possible cause of the failure (guessed by this bot)

@bjorn3
Copy link
Member

bjorn3 commented Feb 1, 2021

@bors r+ retry

@bors
Copy link
Contributor

bors commented Feb 1, 2021

💡 This pull request was already approved, no need to approve it again.

  • This pull request previously failed. You should add more commits to fix the bug, or use retry to trigger a build again.
  • There's another pull request that is currently being tested, blocking this pull request: Rollup of 8 pull requests #81620

@bors
Copy link
Contributor

bors commented Feb 1, 2021

📌 Commit 4105506 has been approved by bjorn3

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Feb 1, 2021
@bjorn3
Copy link
Member

bjorn3 commented Feb 1, 2021

Oops, should have done

@bors r=sfackler

@bors
Copy link
Contributor

bors commented Feb 1, 2021

💡 This pull request was already approved, no need to approve it again.

@bors
Copy link
Contributor

bors commented Feb 1, 2021

📌 Commit 4105506 has been approved by sfackler

henryboisdequin pushed a commit to henryboisdequin/rust that referenced this pull request Feb 1, 2021
Let io::copy reuse BufWriter buffers

This optimization will allow users to implicitly set the buffer size for io::copy by wrapping the writer into a `BufWriter` if the default block size is insufficient, which should fix rust-lang#49921

Due to min_specialization limitations this approach only works with `BufWriter` but not for `BufReader<R>` since `R` is unconstrained and thus the necessary specialization on `R: Read` is not always applicable. Once specialization becomes more powerful this optimization could be extended to look at the reader and writer side and use whichever buffer is larger.
bors added a commit to rust-lang-ci/rust that referenced this pull request Feb 1, 2021
…as-schievink

Rollup of 12 pull requests

Successful merges:

 - rust-lang#78641 (Let io::copy reuse BufWriter buffers)
 - rust-lang#79291 (Add error message for private fn)
 - rust-lang#81364 (Improve `rustc_mir_build::matches` docs)
 - rust-lang#81387 (Move some tests to more reasonable directories - 3)
 - rust-lang#81463 (Rename NLL* to Nll* accordingly to C-CASE)
 - rust-lang#81504 (Suggest accessing field when appropriate)
 - rust-lang#81529 (Fix invalid camel case suggestion involving unicode idents)
 - rust-lang#81536 (Indicate both start and end of pass RSS in time-passes output)
 - rust-lang#81592 (Rustdoc UI fixes)
 - rust-lang#81594 (Avoid building LLVM just for llvm-dwp)
 - rust-lang#81598 (Fix calling convention for CRT startup)
 - rust-lang#81618 (Sync rustc_codegen_cranelift)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit a7a6f01 into rust-lang:master Feb 1, 2021
@rustbot rustbot added this to the 1.51.0 milestone Feb 1, 2021
Comment on lines +122 to +123

writer.flush_buf()?;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think putting this in an else branch will be clearer, if the previous conditions are hit all will either continue or return, it does not reach this part.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

std::io::copy performance may be 20x slower than it could be?
10 participants