-
-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
chore: Avoid allocation if PollSemaphore is unused #3634
Conversation
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.
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 <alice@ryhl.io>
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
PollSemaphore
allocates, even if it ends up unused (e. g. if.try_acquire_owned
is used as a fast-path). This is due to the underlyingReusableBoxFuture
which is always initialized and holding a future.Solution
This turns the
ReusableBoxFuture
optional, 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
NonNull
inside 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
.