1 use criterion::{black_box, criterion_group, criterion_main, Criterion};
2 use std::mem;
3 use std::time::{Duration, Instant};
4 
5 criterion_group!(benches, bench);
6 criterion_main!(benches);
7 
8 macro_rules! bench_send_and_recv {
9     ($c:expr, $($type:ty => $value:expr);+) => {
10         // Sanity check that all $values are of $type.
11         $(let _: $type = $value;)*
12         {
13             let mut group = $c.benchmark_group("create_channel");
14             $(group.bench_function(stringify!($type), |b| {
15                 b.iter(oneshot::channel::<$type>)
16             });)*
17             group.finish();
18         }
19         {
20             let mut group = $c.benchmark_group("create_and_send");
21             $(group.bench_function(stringify!($type), |b| {
22                 b.iter(|| {
23                     let (sender, _receiver) = oneshot::channel();
24                     sender.send(black_box($value)).unwrap()
25                 });
26             });)*
27             group.finish();
28         }
29         {
30             let mut group = $c.benchmark_group("create_and_send_on_closed");
31             $(group.bench_function(stringify!($type), |b| {
32                 b.iter(|| {
33                     let (sender, _) = oneshot::channel();
34                     sender.send(black_box($value)).unwrap_err()
35                 });
36             });)*
37             group.finish();
38         }
39         {
40             let mut group = $c.benchmark_group("create_send_and_recv");
41             $(group.bench_function(stringify!($type), |b| {
42                 b.iter(|| {
43                     let (sender, receiver) = oneshot::channel();
44                     sender.send(black_box($value)).unwrap();
45                     receiver.recv().unwrap()
46                 });
47             });)*
48             group.finish();
49         }
50         {
51             let mut group = $c.benchmark_group("create_send_and_recv_ref");
52             $(group.bench_function(stringify!($type), |b| {
53                 b.iter(|| {
54                     let (sender, receiver) = oneshot::channel();
55                     sender.send(black_box($value)).unwrap();
56                     receiver.recv_ref().unwrap()
57                 });
58             });)*
59             group.finish();
60         }
61     };
62 }
63 
bench(c: &mut Criterion)64 fn bench(c: &mut Criterion) {
65     bench_send_and_recv!(c,
66         () => ();
67         u8 => 7u8;
68         usize => 9876usize;
69         u128 => 1234567u128;
70         [u8; 64] => [0b10101010u8; 64];
71         [u8; 4096] => [0b10101010u8; 4096]
72     );
73 
74     bench_try_recv(c);
75     bench_recv_deadline_now(c);
76     bench_recv_timeout_zero(c);
77 }
78 
bench_try_recv(c: &mut Criterion)79 fn bench_try_recv(c: &mut Criterion) {
80     let (sender, receiver) = oneshot::channel::<u128>();
81     c.bench_function("try_recv_empty", |b| {
82         b.iter(|| receiver.try_recv().unwrap_err())
83     });
84     mem::drop(sender);
85     c.bench_function("try_recv_empty_closed", |b| {
86         b.iter(|| receiver.try_recv().unwrap_err())
87     });
88 }
89 
bench_recv_deadline_now(c: &mut Criterion)90 fn bench_recv_deadline_now(c: &mut Criterion) {
91     let now = Instant::now();
92     {
93         let (_sender, receiver) = oneshot::channel::<u128>();
94         c.bench_function("recv_deadline_now", |b| {
95             b.iter(|| receiver.recv_deadline(now).unwrap_err())
96         });
97     }
98     {
99         let (sender, receiver) = oneshot::channel::<u128>();
100         mem::drop(sender);
101         c.bench_function("recv_deadline_now_closed", |b| {
102             b.iter(|| receiver.recv_deadline(now).unwrap_err())
103         });
104     }
105 }
106 
bench_recv_timeout_zero(c: &mut Criterion)107 fn bench_recv_timeout_zero(c: &mut Criterion) {
108     let zero = Duration::from_nanos(0);
109     {
110         let (_sender, receiver) = oneshot::channel::<u128>();
111         c.bench_function("recv_timeout_zero", |b| {
112             b.iter(|| receiver.recv_timeout(zero).unwrap_err())
113         });
114     }
115     {
116         let (sender, receiver) = oneshot::channel::<u128>();
117         mem::drop(sender);
118         c.bench_function("recv_timeout_zero_closed", |b| {
119             b.iter(|| receiver.recv_timeout(zero).unwrap_err())
120         });
121     }
122 }
123