Files
tokio/benches/latency.rs
T

118 lines
3.0 KiB
Rust
Raw Normal View History

2016-11-04 21:48:34 -07:00
#![feature(test)]
2018-03-06 14:40:09 -08:00
#![deny(warnings)]
2016-11-04 21:48:34 -07:00
extern crate test;
2018-03-06 14:40:09 -08:00
#[macro_use]
2016-11-04 21:48:34 -07:00
extern crate futures;
2017-10-24 16:30:16 -07:00
extern crate tokio;
2016-11-04 21:48:34 -07:00
use std::io;
use std::net::SocketAddr;
2016-11-10 20:10:02 -08:00
use std::thread;
2016-11-04 21:48:34 -07:00
2016-11-10 20:10:02 -08:00
use futures::sync::oneshot;
2016-11-19 10:02:12 -08:00
use futures::sync::mpsc;
2016-11-10 19:50:44 -08:00
use futures::{Future, Poll, Sink, Stream};
2016-11-10 20:10:02 -08:00
use test::Bencher;
2017-10-24 16:30:16 -07:00
use tokio::net::UdpSocket;
2016-11-04 21:48:34 -07:00
/// UDP echo server
struct EchoServer {
2016-11-10 19:50:44 -08:00
socket: UdpSocket,
buf: Vec<u8>,
to_send: Option<(usize, SocketAddr)>,
2016-11-04 21:48:34 -07:00
}
impl EchoServer {
2016-11-10 19:50:44 -08:00
fn new(s: UdpSocket) -> Self {
EchoServer {
2016-11-04 21:48:34 -07:00
socket: s,
to_send: None,
buf: vec![0u8; 1600],
}
}
}
impl Future for EchoServer {
2016-11-04 21:48:34 -07:00
type Item = ();
type Error = io::Error;
fn poll(&mut self) -> Poll<(), io::Error> {
loop {
2016-11-10 14:11:06 -08:00
if let Some(&(size, peer)) = self.to_send.as_ref() {
2018-03-06 14:40:09 -08:00
try_ready!(self.socket.poll_send_to(&self.buf[..size], &peer));
2016-11-10 19:50:44 -08:00
self.to_send = None;
}
2018-03-06 14:40:09 -08:00
self.to_send = Some(try_ready!(self.socket.poll_recv_from(&mut self.buf)));
}
}
}
2016-11-10 14:11:06 -08:00
2016-11-04 21:48:34 -07:00
#[bench]
fn udp_echo_latency(b: &mut Bencher) {
2016-11-10 19:50:44 -08:00
let any_addr = "127.0.0.1:0".to_string();
let any_addr = any_addr.parse::<SocketAddr>().unwrap();
2016-11-04 21:48:34 -07:00
2016-11-10 19:50:44 -08:00
let (stop_c, stop_p) = oneshot::channel::<()>();
let (tx, rx) = oneshot::channel();
2016-11-04 21:48:34 -07:00
let child = thread::spawn(move || {
2018-02-13 22:02:06 +04:00
let socket = tokio::net::UdpSocket::bind(&any_addr).unwrap();
tx.send(socket.local_addr().unwrap()).unwrap();
2016-11-04 21:48:34 -07:00
2016-11-10 19:50:44 -08:00
let server = EchoServer::new(socket);
let server = server.select(stop_p.map_err(|_| panic!()));
let server = server.map_err(|_| ());
2018-02-13 22:02:06 +04:00
server.wait().unwrap();
2016-11-04 21:48:34 -07:00
});
2016-11-10 19:50:44 -08:00
let client = std::net::UdpSocket::bind(&any_addr).unwrap();
2016-11-04 21:48:34 -07:00
2016-11-10 19:50:44 -08:00
let server_addr = rx.wait().unwrap();
2016-11-04 21:48:34 -07:00
let mut buf = [0u8; 1000];
// warmup phase; for some reason initial couple of
2016-11-10 14:11:06 -08:00
// runs are much slower
//
// TODO: Describe the exact reasons; caching? branch predictor? lazy closures?
2016-11-10 14:11:06 -08:00
for _ in 0..8 {
client.send_to(&buf, &server_addr).unwrap();
let _ = client.recv_from(&mut buf).unwrap();
}
2016-11-04 21:48:34 -07:00
b.iter(|| {
client.send_to(&buf, &server_addr).unwrap();
let _ = client.recv_from(&mut buf).unwrap();
});
2018-02-13 22:02:06 +04:00
stop_c.send(()).unwrap();
2016-11-04 21:48:34 -07:00
child.join().unwrap();
}
2016-11-10 20:10:02 -08:00
#[bench]
fn futures_channel_latency(b: &mut Bencher) {
2016-11-19 10:02:12 -08:00
let (mut in_tx, in_rx) = mpsc::channel(32);
let (out_tx, out_rx) = mpsc::channel::<_>(32);
2016-11-10 20:10:02 -08:00
2016-11-19 10:02:12 -08:00
let child = thread::spawn(|| out_tx.send_all(in_rx.then(|r| r.unwrap())).wait());
2016-11-10 20:10:02 -08:00
let mut rx_iter = out_rx.wait();
// warmup phase; for some reason initial couple of runs are much slower
//
// TODO: Describe the exact reasons; caching? branch predictor? lazy closures?
for _ in 0..8 {
2016-11-19 10:02:12 -08:00
in_tx.start_send(Ok(1usize)).unwrap();
2016-11-10 20:10:02 -08:00
let _ = rx_iter.next();
}
b.iter(|| {
2016-11-19 10:02:12 -08:00
in_tx.start_send(Ok(1usize)).unwrap();
2016-11-10 20:10:02 -08:00
let _ = rx_iter.next();
});
drop(in_tx);
child.join().unwrap().unwrap();
}