rust/src/test/bench/pingpong.rs

162 lines
3.7 KiB
Rust
Raw Normal View History

// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// Compare bounded and unbounded protocol performance.
#[allow(structural_records)]; // Pipes
// Until a snapshot
// xfail-pretty
extern mod std;
2012-09-05 14:32:05 -05:00
use pipes::{spawn_service, recv};
use std::time::precise_time_s;
proto! pingpong (
ping: send {
ping -> pong
}
2012-08-22 19:24:52 -05:00
pong: recv {
pong -> ping
}
)
proto! pingpong_unbounded (
ping: send {
ping -> pong
}
2012-08-22 19:24:52 -05:00
pong: recv {
pong -> ping
}
you_will_never_catch_me: send {
never_ever_ever -> you_will_never_catch_me
}
)
// This stuff should go in libcore::pipes
macro_rules! move_it (
{ $x:expr } => { let t = move *ptr::addr_of(&($x)); move t }
)
macro_rules! follow (
2012-08-22 19:24:52 -05:00
{
$($message:path($($x: ident),+) -> $next:ident $e:expr)+
} => (
2012-08-06 14:34:08 -05:00
|m| match move m {
$(Some($message($($x,)* move next)) => {
2012-09-19 00:44:34 -05:00
let $next = move next;
move $e })+
_ => { fail!() }
}
);
2012-08-22 19:24:52 -05:00
{
$($message:path -> $next:ident $e:expr)+
} => (
2012-08-06 14:34:08 -05:00
|m| match move m {
$(Some($message(move next)) => {
2012-09-19 00:44:34 -05:00
let $next = move next;
move $e })+
_ => { fail!() }
2012-08-06 15:17:35 -05:00
}
)
)
2012-12-11 15:50:04 -06:00
fn switch<T: Owned, Tb: Owned, U>(+endp: pipes::RecvPacketBuffered<T, Tb>,
f: fn(+v: Option<T>) -> U) -> U {
2012-09-19 00:44:34 -05:00
f(pipes::try_recv(move endp))
}
// Here's the benchmark
fn bounded(count: uint) {
use pingpong::*;
let mut ch = do spawn_service(init) |ch| {
let mut count = count;
2012-09-19 00:44:34 -05:00
let mut ch = move ch;
while count > 0 {
2012-09-19 00:44:34 -05:00
ch = switch(move ch, follow! (
ping -> next { server::pong(move next) }
2012-08-22 19:24:52 -05:00
));
count -= 1;
}
};
let mut count = count;
while count > 0 {
2012-09-19 00:44:34 -05:00
let ch_ = client::ping(move ch);
2012-09-19 00:44:34 -05:00
ch = switch(move ch_, follow! (
pong -> next { move next }
2012-08-22 19:24:52 -05:00
));
count -= 1;
}
}
fn unbounded(count: uint) {
use pingpong_unbounded::*;
let mut ch = do spawn_service(init) |ch| {
let mut count = count;
2012-09-19 00:44:34 -05:00
let mut ch = move ch;
while count > 0 {
2012-09-19 00:44:34 -05:00
ch = switch(move ch, follow! (
ping -> next { server::pong(move next) }
2012-08-22 19:24:52 -05:00
));
count -= 1;
}
};
let mut count = count;
while count > 0 {
2012-09-19 00:44:34 -05:00
let ch_ = client::ping(move ch);
2012-09-19 00:44:34 -05:00
ch = switch(move ch_, follow! (
pong -> next { move next }
2012-08-22 19:24:52 -05:00
));
count -= 1;
}
}
fn timeit(f: fn()) -> float {
let start = precise_time_s();
f();
let stop = precise_time_s();
stop - start
}
fn main() {
2012-08-06 15:17:35 -05:00
let count = if os::getenv(~"RUST_BENCH").is_some() {
250000
} else {
100
};
let bounded = do timeit { bounded(count) };
let unbounded = do timeit { unbounded(count) };
2012-08-22 19:24:52 -05:00
io::println(fmt!("count: %?\n", count));
io::println(fmt!("bounded: %? s\t(%? μs/message)",
bounded, bounded * 1000000. / (count as float)));
io::println(fmt!("unbounded: %? s\t(%? μs/message)",
unbounded, unbounded * 1000000. / (count as float)));
2012-08-22 19:24:52 -05:00
io::println(fmt!("\n\
bounded is %?%% faster",
2012-08-22 19:24:52 -05:00
(unbounded - bounded) / bounded * 100.));
}