commonware_runtime/benchmarks/tokio.rs
1//! Implements a [criterion]-compatible executor for the [tokio] runtime.
2
3use super::context;
4use crate::{tokio, Runner};
5use criterion::async_executor::AsyncExecutor;
6use futures::Future;
7
8/// A [criterion]-compatible executor for the [tokio] runtime.
9///
10/// # Example
11///
12/// ```rust
13/// use criterion::{criterion_group, criterion_main, Criterion, BatchSize};
14/// use commonware_runtime::{Clock, benchmarks::{context, tokio}};
15/// use std::time::Duration;
16///
17/// fn my_benchmark(c: &mut Criterion) {
18/// let executor = tokio::Executor::default();
19/// c.bench_function("sleep_benchmark", |b| {
20/// b.to_async(&executor).iter_batched(|| (),
21/// |_| async {
22/// // Get the context
23/// let ctx = context::get::<commonware_runtime::tokio::Context>();
24/// // Use context features
25/// ctx.sleep(Duration::from_micros(10)).await;
26/// }, BatchSize::SmallInput);
27/// });
28/// }
29/// ```
30#[derive(Clone)]
31pub struct Executor {
32 cfg: tokio::Config,
33}
34
35impl Executor {
36 /// Create a new bencher with the given configuration
37 pub fn new(cfg: tokio::Config) -> Self {
38 Self { cfg }
39 }
40}
41
42impl Default for Executor {
43 fn default() -> Self {
44 Self::new(tokio::Config::default())
45 }
46}
47
48impl AsyncExecutor for &Executor {
49 fn block_on<T>(&self, future: impl Future<Output = T>) -> T {
50 // Create and store our context
51 let (executor, context) = tokio::Executor::init(self.cfg.clone());
52 context::set(context);
53
54 // Run the future
55 let result = executor.start(future);
56
57 // Clean up
58 context::clear();
59
60 result
61 }
62}