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