Files
cli/vendor/tungstenite/benches/read.rs

93 lines
2.9 KiB
Rust

//! Benchmarks for read performance.
use criterion::{BatchSize, Criterion};
use std::{
io::{self, Read, Write},
sync::{Arc, Mutex},
};
use tungstenite::{protocol::Role, Message, WebSocket};
/// Mock stream with no artificial delays.
#[derive(Default, Clone)]
struct MockIo(Arc<Mutex<Vec<u8>>>);
impl Read for MockIo {
fn read(&mut self, to: &mut [u8]) -> io::Result<usize> {
let mut data = self.0.lock().unwrap();
if data.is_empty() {
return Err(io::Error::new(io::ErrorKind::WouldBlock, "not ready"));
}
let len = data.len().min(to.len());
to[..len].copy_from_slice(data.drain(..len).as_slice());
Ok(len)
}
}
impl Write for MockIo {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.0.lock().unwrap().write(buf)
}
fn flush(&mut self) -> io::Result<()> {
Ok(())
}
}
fn benchmark(c: &mut Criterion) {
/// Benchmark reading 100k mix of binary & text messages.
fn read_100k(role: Role, b: &mut criterion::Bencher<'_>) {
let io = MockIo::default();
let mut writer = WebSocket::from_raw_socket(
io.clone(),
match role {
Role::Client => Role::Server,
Role::Server => Role::Client,
},
None,
);
let mut ws = WebSocket::from_raw_socket(io, role, None);
b.iter_batched(
|| {
let mut sum = 0;
for i in 0_u64..100_000 {
writer
.send(match i {
_ if i % 3 == 0 => Message::binary(i.to_le_bytes().to_vec()),
_ => Message::text(format!("{{\"id\":{i}}}")),
})
.unwrap();
sum += i;
}
sum
},
|expected_sum| {
let mut sum = 0;
while sum != expected_sum {
match ws.read().unwrap() {
Message::Binary(v) => {
let a: &[u8; 8] = v.as_ref().try_into().unwrap();
sum += u64::from_le_bytes(*a);
}
Message::Text(msg) => {
let i: u64 = msg.as_str()[6..msg.len() - 1].parse().unwrap();
sum += i;
}
m => panic!("Unexpected {m}"),
}
}
},
BatchSize::SmallInput,
);
}
c.bench_function("read+unmask 100k small messages (server)", |b| {
read_100k(Role::Server, b);
});
c.bench_function("read 100k small messages (client)", |b| {
read_100k(Role::Client, b);
});
}
criterion::criterion_group!(read_benches, benchmark);
criterion::criterion_main!(read_benches);