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
14use 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.
20pub 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")]
27pub struct FuturesExecutor;
28#[cfg(feature = "async_futures")]
29impl 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")]
37pub struct SmolExecutor;
38#[cfg(feature = "async_smol")]
39impl 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")]
46impl 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")]
52impl 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")]
60pub struct AsyncStdExecutor;
61#[cfg(feature = "async_std")]
62impl 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