| 1 | //! This module defines a trait that can be used to plug in different Futures executors into
|
| 2 | //! Criterion.rs' async benchmarking support.
|
| 3 | //!
|
| 4 | //! Implementations are provided for:
|
| 5 | //! * Tokio (implemented directly for tokio::Runtime)
|
| 6 | //! * Async-std
|
| 7 | //! * Smol
|
| 8 | //! * The Futures crate
|
| 9 | //!
|
| 10 | //! Please note that async benchmarks will have a small amount of measurement overhead relative
|
| 11 | //! to synchronous benchmarks. It is recommended to use synchronous benchmarks where possible, to
|
| 12 | //! improve measurement accuracy.
|
| 13 |
|
| 14 | use std::future::Future;
|
| 15 |
|
| 16 | /// Plugin trait used to allow benchmarking on multiple different async runtimes.
|
| 17 | ///
|
| 18 | /// Smol, Tokio and Async-std are supported out of the box, as is the current-thread runner from the
|
| 19 | /// Futures crate; it is recommended to use whichever runtime you use in production.
|
| 20 | pub trait AsyncExecutor {
|
| 21 | /// Spawn the given future onto this runtime and block until it's complete, returning the result.
|
| 22 | fn block_on<T>(&self, future: impl Future<Output = T>) -> T;
|
| 23 | }
|
| 24 |
|
| 25 | /// Runs futures on the 'futures' crate's built-in current-thread executor
|
| 26 | #[cfg (feature = "async_futures" )]
|
| 27 | pub struct FuturesExecutor;
|
| 28 | #[cfg (feature = "async_futures" )]
|
| 29 | impl AsyncExecutor for FuturesExecutor {
|
| 30 | fn block_on<T>(&self, future: impl Future<Output = T>) -> T {
|
| 31 | futures::executor::block_on(future)
|
| 32 | }
|
| 33 | }
|
| 34 |
|
| 35 | /// Runs futures on the 'smol' crate's global executor
|
| 36 | #[cfg (feature = "async_smol" )]
|
| 37 | pub struct SmolExecutor;
|
| 38 | #[cfg (feature = "async_smol" )]
|
| 39 | impl AsyncExecutor for SmolExecutor {
|
| 40 | fn block_on<T>(&self, future: impl Future<Output = T>) -> T {
|
| 41 | smol::block_on(future)
|
| 42 | }
|
| 43 | }
|
| 44 |
|
| 45 | #[cfg (feature = "async_tokio" )]
|
| 46 | impl AsyncExecutor for tokio::runtime::Runtime {
|
| 47 | fn block_on<T>(&self, future: impl Future<Output = T>) -> T {
|
| 48 | self.block_on(future)
|
| 49 | }
|
| 50 | }
|
| 51 | #[cfg (feature = "async_tokio" )]
|
| 52 | impl AsyncExecutor for &tokio::runtime::Runtime {
|
| 53 | fn block_on<T>(&self, future: impl Future<Output = T>) -> T {
|
| 54 | (*self).block_on(future)
|
| 55 | }
|
| 56 | }
|
| 57 |
|
| 58 | /// Runs futures on the 'async-std' crate's global executor
|
| 59 | #[cfg (feature = "async_std" )]
|
| 60 | pub struct AsyncStdExecutor;
|
| 61 | #[cfg (feature = "async_std" )]
|
| 62 | impl AsyncExecutor for AsyncStdExecutor {
|
| 63 | fn block_on<T>(&self, future: impl Future<Output = T>) -> T {
|
| 64 | async_std::task::block_on(future)
|
| 65 | }
|
| 66 | }
|
| 67 | |