-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
chore: Avoid allocation if PollSemaphore is unused #3634
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
chore: Avoid allocation if PollSemaphore is unused #3634
Conversation
Darksonn
left a comment
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 PR.
| pub struct PollSemaphore { | ||
| semaphore: Arc<Semaphore>, | ||
| permit_fut: ReusableBoxFuture<Result<OwnedSemaphorePermit, AcquireError>>, | ||
| permit_fut: Option<ReusableBoxFuture<Result<OwnedSemaphorePermit, AcquireError>>>, |
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.
Another alternative that sometimes works is to initialize the ReusableBoxFuture with a zero-sized future, which also would not allocate. But it probably doesn't help much in this specific case.
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.
Yup! But that wouldn't let us fast-path .try_acquire anymore without an explicit flag, would it?
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.
Yeah, I don't think it would help here, but it could be done for PollSender, and maybe also the watch/broadcast wrappers in tokio-stream.
c99fd36 to
4cd3c57
Compare
|
Thank you for the feedback ❤️ I added another commit adding a fast-path for when a permit is immediately available. |
Co-authored-by: Alice Ryhl <[email protected]>
|
Thank you for the PR. 😃 |
Such a PR would be accepted. The same is also the case for the broadcast and watch wrappers in tokio-stream. |
|
🎉 |
Motivation
Cloning
PollSemaphoreallocates, even if it ends up unused (e. g. if.try_acquire_ownedis used as a fast-path). This is due to the underlyingReusableBoxFuturewhich is always initialized and holding a future.Solution
This turns the
ReusableBoxFutureoptional, and only initializes it on the first call to.poll_acquire, when it's actually needed.The size of the semaphore doesn't change, rustc is able to exploit the niche in
NonNullinside ofReusableBoxFuture, but this does introduce an additional branch, so not sure this optimization is worth it in the end.If desired I can file a similar PR for
PollSender.