1 #![feature(test)]
2 
3 extern crate test;
4 use crate::test::Bencher;
5 
6 use futures::executor::block_on;
7 use futures::future::Future;
8 use futures::task::{Context, Poll, Waker};
9 use std::pin::Pin;
10 
11 #[bench]
thread_yield_single_thread_one_wait(b: &mut Bencher)12 fn thread_yield_single_thread_one_wait(b: &mut Bencher) {
13     const NUM: usize = 10_000;
14 
15     struct Yield {
16         rem: usize,
17     }
18 
19     impl Future for Yield {
20         type Output = ();
21 
22         fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
23             if self.rem == 0 {
24                 Poll::Ready(())
25             } else {
26                 self.rem -= 1;
27                 cx.waker().wake_by_ref();
28                 Poll::Pending
29             }
30         }
31     }
32 
33     b.iter(|| {
34         let y = Yield { rem: NUM };
35         block_on(y);
36     });
37 }
38 
39 #[bench]
thread_yield_single_thread_many_wait(b: &mut Bencher)40 fn thread_yield_single_thread_many_wait(b: &mut Bencher) {
41     const NUM: usize = 10_000;
42 
43     struct Yield {
44         rem: usize,
45     }
46 
47     impl Future for Yield {
48         type Output = ();
49 
50         fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
51             if self.rem == 0 {
52                 Poll::Ready(())
53             } else {
54                 self.rem -= 1;
55                 cx.waker().wake_by_ref();
56                 Poll::Pending
57             }
58         }
59     }
60 
61     b.iter(|| {
62         for _ in 0..NUM {
63             let y = Yield { rem: 1 };
64             block_on(y);
65         }
66     });
67 }
68 
69 #[bench]
thread_yield_multi_thread(b: &mut Bencher)70 fn thread_yield_multi_thread(b: &mut Bencher) {
71     use std::sync::mpsc;
72     use std::thread;
73 
74     const NUM: usize = 1_000;
75 
76     let (tx, rx) = mpsc::sync_channel::<Waker>(10_000);
77 
78     struct Yield {
79         rem: usize,
80         tx: mpsc::SyncSender<Waker>,
81     }
82     impl Unpin for Yield {}
83 
84     impl Future for Yield {
85         type Output = ();
86 
87         fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
88             if self.rem == 0 {
89                 Poll::Ready(())
90             } else {
91                 self.rem -= 1;
92                 self.tx.send(cx.waker().clone()).unwrap();
93                 Poll::Pending
94             }
95         }
96     }
97 
98     thread::spawn(move || {
99         while let Ok(task) = rx.recv() {
100             task.wake();
101         }
102     });
103 
104     b.iter(move || {
105         let y = Yield { rem: NUM, tx: tx.clone() };
106 
107         block_on(y);
108     });
109 }
110