#![cfg(feature = "broken")] #![feature(test)] #![warn(rust_2018_idioms)] extern crate test; mod tokio { use futures::{future, Async, Future}; use test::Bencher; use tokio_sync::oneshot; #[bench] fn new(b: &mut Bencher) { b.iter(|| { let _ = ::test::black_box(&oneshot::channel::()); }) } #[bench] fn same_thread_send_recv(b: &mut Bencher) { b.iter(|| { let (tx, mut rx) = oneshot::channel(); let _ = tx.send(1); assert_eq!(Async::Ready(1), rx.poll().unwrap()); }); } #[bench] fn same_thread_recv_multi_send_recv(b: &mut Bencher) { b.iter(|| { let (tx, mut rx) = oneshot::channel(); future::lazy(|| { let _ = rx.poll(); let _ = rx.poll(); let _ = rx.poll(); let _ = rx.poll(); let _ = tx.send(1); assert_eq!(Async::Ready(1), rx.poll().unwrap()); Ok::<_, ()>(()) }) .wait() .unwrap(); }); } #[bench] fn multi_thread_send_recv(b: &mut Bencher) { const MAX: usize = 10_000_000; use std::thread; fn spin(mut f: F) -> Result { use futures::Async::Ready; loop { match f.poll() { Ok(Ready(v)) => return Ok(v), Ok(_) => {} Err(e) => return Err(e), } } } let mut ping_txs = vec![]; let mut ping_rxs = vec![]; let mut pong_txs = vec![]; let mut pong_rxs = vec![]; for _ in 0..MAX { let (tx, rx) = oneshot::channel::<()>(); ping_txs.push(Some(tx)); ping_rxs.push(Some(rx)); let (tx, rx) = oneshot::channel::<()>(); pong_txs.push(Some(tx)); pong_rxs.push(Some(rx)); } thread::spawn(move || { future::lazy(|| { for i in 0..MAX { let ping_rx = ping_rxs[i].take().unwrap(); let pong_tx = pong_txs[i].take().unwrap(); if spin(ping_rx).is_err() { return Ok(()); } pong_tx.send(()).unwrap(); } Ok::<(), ()>(()) }) .wait() .unwrap(); }); future::lazy(|| { let mut i = 0; b.iter(|| { let ping_tx = ping_txs[i].take().unwrap(); let pong_rx = pong_rxs[i].take().unwrap(); ping_tx.send(()).unwrap(); spin(pong_rx).unwrap(); i += 1; }); Ok::<(), ()>(()) }) .wait() .unwrap(); } } mod legacy { use futures::sync::oneshot; use futures::{future, Async, Future}; use test::Bencher; #[bench] fn new(b: &mut Bencher) { b.iter(|| { let _ = ::test::black_box(&oneshot::channel::()); }) } #[bench] fn same_thread_send_recv(b: &mut Bencher) { b.iter(|| { let (tx, mut rx) = oneshot::channel(); let _ = tx.send(1); assert_eq!(Async::Ready(1), rx.poll().unwrap()); }); } #[bench] fn same_thread_recv_multi_send_recv(b: &mut Bencher) { b.iter(|| { let (tx, mut rx) = oneshot::channel(); future::lazy(|| { let _ = rx.poll(); let _ = rx.poll(); let _ = rx.poll(); let _ = rx.poll(); let _ = tx.send(1); assert_eq!(Async::Ready(1), rx.poll().unwrap()); Ok::<_, ()>(()) }) .wait() .unwrap(); }); } #[bench] fn multi_thread_send_recv(b: &mut Bencher) { const MAX: usize = 10_000_000; use std::thread; fn spin(mut f: F) -> Result { use futures::Async::Ready; loop { match f.poll() { Ok(Ready(v)) => return Ok(v), Ok(_) => {} Err(e) => return Err(e), } } } let mut ping_txs = vec![]; let mut ping_rxs = vec![]; let mut pong_txs = vec![]; let mut pong_rxs = vec![]; for _ in 0..MAX { let (tx, rx) = oneshot::channel::<()>(); ping_txs.push(Some(tx)); ping_rxs.push(Some(rx)); let (tx, rx) = oneshot::channel::<()>(); pong_txs.push(Some(tx)); pong_rxs.push(Some(rx)); } thread::spawn(move || { future::lazy(|| { for i in 0..MAX { let ping_rx = ping_rxs[i].take().unwrap(); let pong_tx = pong_txs[i].take().unwrap(); if spin(ping_rx).is_err() { return Ok(()); } pong_tx.send(()).unwrap(); } Ok::<(), ()>(()) }) .wait() .unwrap(); }); future::lazy(|| { let mut i = 0; b.iter(|| { let ping_tx = ping_txs[i].take().unwrap(); let pong_rx = pong_rxs[i].take().unwrap(); ping_tx.send(()).unwrap(); spin(pong_rx).unwrap(); i += 1; }); Ok::<(), ()>(()) }) .wait() .unwrap(); } }