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 | |