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

Specialize some methods of io::Chain #105917

Merged
merged 3 commits into from
Feb 19, 2024
Merged

Conversation

a1phyr
Copy link
Contributor

@a1phyr a1phyr commented Dec 19, 2022

This PR specializes the implementation of some methods of io::Chain, which could bring performance improvements when using it.

@rustbot
Copy link
Collaborator

rustbot commented Dec 19, 2022

r? @m-ou-se

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

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Dec 19, 2022
@rustbot
Copy link
Collaborator

rustbot commented Dec 19, 2022

Hey! It looks like you've submitted a new PR for the library teams!

If this PR contains changes to any rust-lang/rust public library APIs then please comment with @rustbot label +T-libs-api -T-libs to tag it appropriately. If this PR contains changes to any unstable APIs please edit the PR description to add a link to the relevant API Change Proposal or create one if you haven't already. If you're unsure where your change falls no worries, just leave it as is and the reviewer will take a look and make a decision to forward on if necessary.

Examples of T-libs-api changes:

  • Stabilizing library features
  • Introducing insta-stable changes such as new implementations of existing stable traits on existing stable types
  • Introducing new or changing existing unstable library APIs (excluding permanently unstable features / features without a tracking issue)
  • Changing public documentation in ways that create new stability guarantees
  • Changing observable runtime behavior of library APIs

@a1phyr a1phyr changed the title Read chain more impls Specialize some methods of io::Chain Dec 19, 2022
@rust-log-analyzer

This comment has been minimized.

library/std/src/io/mod.rs Outdated Show resolved Hide resolved
library/std/src/io/mod.rs Outdated Show resolved Hide resolved
@m-ou-se m-ou-se added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Dec 28, 2022
@pitaj
Copy link
Contributor

pitaj commented Jan 27, 2023

If you resolved all issues brought up in the review, you should use the bot to mark it as waiting-on-review

@a1phyr
Copy link
Contributor Author

a1phyr commented Jan 27, 2023

@rustbot label -S-waiting-on-author +S-waiting-on-review

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Jan 27, 2023
@a1phyr
Copy link
Contributor Author

a1phyr commented Jan 27, 2023

I didn't know I can do that myself ! Thanks !

@a1phyr a1phyr requested a review from m-ou-se January 31, 2023 23:13
@anden3 anden3 added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels May 14, 2023
@a1phyr
Copy link
Contributor Author

a1phyr commented Jun 12, 2023

I have removed read_to_string specialization: an error would happen if an UTF8 sequence were split between the two readers.
I have also added a test for that case.

@tgross35
Copy link
Contributor

Are you able to run a quick benchmark that shows this being faster? I'm positive it will be faster, but it never hurts to have something to back up added complexity for the sake of performance.

We could do a perf run on this in any case, but I don't expect this change to be exercised much in that run.

(side note, @rustbot ready does the same thing as manually swapping those two labels out)

@workingjubilee
Copy link
Member

Looks good. Can you do the squishy-squishy for the last two commits?

r? workingjubilee
@rustbot author

@rustbot rustbot assigned workingjubilee and unassigned m-ou-se Jul 26, 2023
@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jul 26, 2023
@workingjubilee
Copy link
Member

We could do a perf run on this in any case, but I don't expect this change to be exercised much in that run.

I don't think there's a single instance of this type in the compiler?

@workingjubilee
Copy link
Member

Mostly it's confusing to see a commit that introduces something and then immediately see its removal while navigating the repo's history, so it's just noise in the blame.

@workingjubilee
Copy link
Member

Making sure I get to this soon.
@rustbot ready

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Jul 28, 2023
Comment on lines +2393 to +2396
#[inline]
fn is_read_vectored(&self) -> bool {
self.first.is_read_vectored() || self.second.is_read_vectored()
}
Copy link
Member

@workingjubilee workingjubilee Jul 30, 2023

Choose a reason for hiding this comment

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

Shouldn't this require both to be efficient? I could be persuaded otherwise, certainly, but can you explain why you chose this logic instead? If one half of the chain doesn't have an efficient implementation, then why is the chained type efficient? At the extreme end, we're allowed to apply Chain recursively, so this version you propose would yield true even if we'd chained 16 different things together and only 1 reported true...

Suggested change
#[inline]
fn is_read_vectored(&self) -> bool {
self.first.is_read_vectored() || self.second.is_read_vectored()
}
#[inline]
fn is_read_vectored(&self) -> bool {
self.first.is_read_vectored() & self.second.is_read_vectored()
}

Copy link
Member

Choose a reason for hiding this comment

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

I guess you could also use a more complicated answer which checks done_first, but that seems prone to confusion, even if it might be "more accurate".

library/std/src/io/mod.rs Show resolved Hide resolved
@workingjubilee
Copy link
Member

Waiting on discussion a bit, so
@rustbot author

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jul 31, 2023
@workingjubilee
Copy link
Member

Also, I can accept this as-is without the is_read_vectored change and that could be handled separately.

@JohnCSimon
Copy link
Member

@a1phyr

ping from triage - can you post your status on this PR? There hasn't been an update in month - you seem close to getting this into a mergable state.

FYI: when a PR is ready for review, send a message containing
@rustbot ready to switch to S-waiting-on-review so the PR is in the reviewer's backlog.

@a1phyr
Copy link
Contributor Author

a1phyr commented Dec 4, 2023

Well there is debate over the implementation of is_read_vectored.

I initially used self.first.is_read_vectored() || self.second.is_read_vectored().
@workingjubilee suggested self.first.is_read_vectored() && self.second.is_read_vectored().
And there are the more "correct" implementations based on self.done_first, but I don't expect people calling this function more than once so this may just be confusing.

@workingjubilee
Copy link
Member

Indeed. I'm not entirely sure what the rationale is for the || version? But I tried to explain why I think the && version is more appropriate. I agree that using the "technically correct" implementation seems pointless/confusing.

@workingjubilee
Copy link
Member

I'm happy to be persuaded? It just doesn't feel obvious atm.

@a1phyr
Copy link
Contributor Author

a1phyr commented Jan 16, 2024

Well, the rationale is mostly the same: if we chain 16 types and only one returns false, we would lose a lot of perf.

The main difference is that vectored I/O can significantly improve perf, but has a small cost when used with a single buffer (a indirection on the stack). This is why WASI doesn't have an equivalent of read, only readv (https://docs.rs/wasi/latest/wasi/fn.fd_read.html).

So even with half the chain not vectored, having vectored I/O for the other is usually interesting.

@workingjubilee
Copy link
Member

Hmm. I see. WASI only providing readv does indeed feel persuasive.

@bors r+

@bors
Copy link
Contributor

bors commented Feb 18, 2024

📌 Commit ebc5970 has been approved by workingjubilee

It is now in the queue for this repository.

@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-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Feb 18, 2024
@bors
Copy link
Contributor

bors commented Feb 19, 2024

⌛ Testing commit ebc5970 with merge bea5beb...

@bors
Copy link
Contributor

bors commented Feb 19, 2024

☀️ Test successful - checks-actions
Approved by: workingjubilee
Pushing bea5beb to master...

1 similar comment
@bors
Copy link
Contributor

bors commented Feb 19, 2024

☀️ Test successful - checks-actions
Approved by: workingjubilee
Pushing bea5beb to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Feb 19, 2024
@bors bors merged commit bea5beb into rust-lang:master Feb 19, 2024
12 checks passed
@rustbot rustbot added this to the 1.78.0 milestone Feb 19, 2024
@rust-timer
Copy link
Collaborator

Finished benchmarking commit (bea5beb): comparison URL.

Overall result: no relevant changes - no action needed

@rustbot label: -perf-regression

Instruction count

This benchmark run did not return any relevant results for this metric.

Max RSS (memory usage)

Results

This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
3.5% [2.5%, 4.4%] 2
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
-2.0% [-2.0%, -2.0%] 1
All ❌✅ (primary) - - 0

Cycles

Results

This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.

mean range count
Regressions ❌
(primary)
3.2% [2.8%, 3.8%] 3
Regressions ❌
(secondary)
- - 0
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
-2.8% [-3.5%, -2.1%] 3
All ❌✅ (primary) 3.2% [2.8%, 3.8%] 3

Binary size

This benchmark run did not return any relevant results for this metric.

Bootstrap: 640.888s -> 640.916s (0.00%)
Artifact size: 308.82 MiB -> 308.79 MiB (-0.01%)

@a1phyr a1phyr deleted the read_chain_more_impls branch March 12, 2024 17:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
merged-by-bors This PR was explicitly merged by bors. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-libs Relevant to the library team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.