10 releases (4 breaking)
0.5.9 |
|
---|---|
0.5.0 | Mar 13, 2021 |
0.4.2 | Oct 11, 2020 |
0.3.3 | Aug 25, 2020 |
0.1.0 | May 30, 2019 |
#14 in #oneshot
22,361 downloads per month
Used in 43 crates
(17 directly)
16KB
252 lines
async-oneshot
A fast, small, full-featured, async-aware oneshot channel.
Features:
- Blazing fast! See
Performance
section below. - Tiny code, only one dependency and a lightning quick build.
- Complete
no_std
support (withalloc
forArc
). - Unique feature: sender may wait for a receiver to be waiting.
Usage
#[test]
fn success_one_thread() {
let (s,r) = oneshot::<bool>();
assert_eq!((), s.send(true).unwrap());
assert_eq!(Ok(true), future::block_on(r));
}
Performance
async-oneshot comes with a benchmark suite which you can run with
cargo bench
.
All benches are single-threaded and take double digit nanoseconds on
my machine. async benches use futures_lite::future::block_on
as an
executor.
Numbers from my machine
Here are benchmark numbers from my primary machine, a Ryzen 9 3900X running alpine linux 3.12 that I attempted to peg at maximum cpu:
create_destroy time: [51.596 ns 51.710 ns 51.835 ns]
send/success time: [13.080 ns 13.237 ns 13.388 ns]
send/closed time: [25.304 ns 25.565 ns 25.839 ns]
try_recv/success time: [26.136 ns 26.246 ns 26.335 ns]
try_recv/empty time: [10.764 ns 11.161 ns 11.539 ns]
try_recv/closed time: [27.048 ns 27.159 ns 27.248 ns]
async.recv/success time: [30.532 ns 30.774 ns 31.011 ns]
async.recv/closed time: [28.112 ns 28.208 ns 28.287 ns]
async.wait/success time: [56.449 ns 56.603 ns 56.737 ns]
async.wait/closed time: [34.014 ns 34.154 ns 34.294 ns]
In short, we are very fast. Close to optimal, I think.
Compared to other libraries
The oneshot channel in futures
isn't very fast by comparison.
Tokio put up an excellent fight and made us work hard to improve. In general I'd say we're slightly faster overall, but it's incredibly tight.
Note on safety
This crate uses UnsafeCell and manually synchronises with atomic bitwise ops for performance. We believe it is correct, but we would welcome more eyes on it.
See Also
- async-oneshot-local (single threaded)
- async-spsc (SPSC)
- async-channel (MPMC)
Note on benchmarking
The benchmarks are synthetic and a bit of fun.
Changelog
v0.5.0
Breaking changes:
- Make
Sender.send()
only take a mut ref instead of move.
v0.4.2
Improvements:
- Added some tests to cover repeated fix released in last version.
- Inline more aggressively for some nice benchmark boosts.
v0.4.1
Fixes:
- Remove some overzealous
debug_assert
s that caused crashes in development in case of repeated waking. Thanks @nazar-pc!
Improvements:
- Better benchmarks, based on criterion.
v0.4.0
Breaking changes:
Sender.wait()
's function signature has changed to be a non-async fn
returning animpl Future
. This reduces binary size, runtime and possibly memory usage too. Thanks @zserik!
Fixes:
- Race condition where the sender closes in a narrow window during receiver poll and doesn't wake the Receiver. Thanks @zserik!
Improvements:
- Static assertions. Thanks @zserik!
v0.3.3
Improvements:
- Update
futures-micro
and improve the tests
v0.3.2
Fixes:
- Segfault when dropping receiver. Caused by a typo, d'oh! Thanks @boardwalk!
v0.3.1
Improvements:
- Remove redundant use of ManuallyDrop with UnsafeCell. Thanks @cynecx!
v0.3.0
Improvements:
- Rewrote, benchmarked and optimised.
v0.2.0
- First real release.
Copyright and License
Copyright (c) 2020 James Laver, async-oneshot contributors.
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
Dependencies
~61KB