#![feature(test)] extern crate test; use crate::test::Bencher; use futures::executor::block_on; use futures::future::Future; use futures::task::{Context, Poll, Waker}; use std::pin::Pin; #[bench] fn thread_yield_single_thread_one_wait(b: &mut Bencher) { const NUM: usize = 10_000; struct Yield { rem: usize, } impl Future for Yield { type Output = (); fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { if self.rem == 0 { Poll::Ready(()) } else { self.rem -= 1; cx.waker().wake_by_ref(); Poll::Pending } } } b.iter(|| { let y = Yield { rem: NUM }; block_on(y); }); } #[bench] fn thread_yield_single_thread_many_wait(b: &mut Bencher) { const NUM: usize = 10_000; struct Yield { rem: usize, } impl Future for Yield { type Output = (); fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { if self.rem == 0 { Poll::Ready(()) } else { self.rem -= 1; cx.waker().wake_by_ref(); Poll::Pending } } } b.iter(|| { for _ in 0..NUM { let y = Yield { rem: 1 }; block_on(y); } }); } #[bench] fn thread_yield_multi_thread(b: &mut Bencher) { use std::sync::mpsc; use std::thread; const NUM: usize = 1_000; let (tx, rx) = mpsc::sync_channel::(10_000); struct Yield { rem: usize, tx: mpsc::SyncSender, } impl Unpin for Yield {} impl Future for Yield { type Output = (); fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { if self.rem == 0 { Poll::Ready(()) } else { self.rem -= 1; self.tx.send(cx.waker().clone()).unwrap(); Poll::Pending } } } thread::spawn(move || { while let Ok(task) = rx.recv() { task.wake(); } }); b.iter(move || { let y = Yield { rem: NUM, tx: tx.clone() }; block_on(y); }); }