285 lines
8.2 KiB
Rust
285 lines
8.2 KiB
Rust
use announcement::Announcement;
|
|
use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion, Throughput};
|
|
use std::collections::HashMap;
|
|
use std::hint::black_box;
|
|
use std::sync::Arc;
|
|
|
|
// Small type: 4 bytes
|
|
fn bench_small_type(c: &mut Criterion) {
|
|
let mut group = c.benchmark_group("small_type_i32");
|
|
|
|
for n in [1, 10, 100, 500].iter() {
|
|
group.throughput(Throughput::Elements(*n as u64));
|
|
|
|
// Direct Clone
|
|
group.bench_with_input(BenchmarkId::new("direct_clone", n), n, |b, &n| {
|
|
b.iter(|| {
|
|
let (tx, announcement) = Announcement::new();
|
|
|
|
let mut listeners = Vec::new();
|
|
for _ in 0..n {
|
|
listeners.push(announcement.listener());
|
|
}
|
|
|
|
tx.announce(42i32).unwrap();
|
|
|
|
for listener in listeners {
|
|
black_box(listener.try_listen());
|
|
}
|
|
});
|
|
});
|
|
|
|
// Arc<i32> Clone
|
|
group.bench_with_input(BenchmarkId::new("arc_clone", n), n, |b, &n| {
|
|
b.iter(|| {
|
|
let (tx, announcement) = Announcement::new();
|
|
|
|
let mut listeners = Vec::new();
|
|
for _ in 0..n {
|
|
listeners.push(announcement.listener());
|
|
}
|
|
|
|
tx.announce(Arc::new(42i32)).unwrap();
|
|
|
|
for listener in listeners {
|
|
black_box(listener.try_listen());
|
|
}
|
|
});
|
|
});
|
|
}
|
|
group.finish();
|
|
}
|
|
|
|
// Medium type: 1KB
|
|
fn bench_medium_type(c: &mut Criterion) {
|
|
let mut group = c.benchmark_group("medium_type_1kb");
|
|
|
|
for n in [1, 10, 100, 500].iter() {
|
|
group.throughput(Throughput::Elements(*n as u64));
|
|
|
|
// Direct Clone
|
|
group.bench_with_input(BenchmarkId::new("direct_clone", n), n, |b, &n| {
|
|
b.iter(|| {
|
|
let (tx, announcement) = Announcement::new();
|
|
|
|
let mut listeners = Vec::new();
|
|
for _ in 0..n {
|
|
listeners.push(announcement.listener());
|
|
}
|
|
|
|
tx.announce([0u8; 1024]).unwrap();
|
|
|
|
for listener in listeners {
|
|
black_box(listener.try_listen());
|
|
}
|
|
});
|
|
});
|
|
|
|
// Arc Clone
|
|
group.bench_with_input(BenchmarkId::new("arc_clone", n), n, |b, &n| {
|
|
b.iter(|| {
|
|
let (tx, announcement) = Announcement::new();
|
|
|
|
let mut listeners = Vec::new();
|
|
for _ in 0..n {
|
|
listeners.push(announcement.listener());
|
|
}
|
|
|
|
tx.announce(Arc::new([0u8; 1024])).unwrap();
|
|
|
|
for listener in listeners {
|
|
black_box(listener.try_listen());
|
|
}
|
|
});
|
|
});
|
|
}
|
|
group.finish();
|
|
}
|
|
|
|
// Large type: 1MB
|
|
fn bench_large_type(c: &mut Criterion) {
|
|
let mut group = c.benchmark_group("large_type_1mb");
|
|
group.sample_size(10); // Reduce sample size for large data
|
|
|
|
for n in [1, 10, 100, 500].iter() {
|
|
group.throughput(Throughput::Elements(*n as u64));
|
|
|
|
// Direct Clone
|
|
group.bench_with_input(BenchmarkId::new("direct_clone", n), n, |b, &n| {
|
|
b.iter(|| {
|
|
let (tx, announcement) = Announcement::new();
|
|
|
|
let mut listeners = Vec::new();
|
|
for _ in 0..n {
|
|
listeners.push(announcement.listener());
|
|
}
|
|
|
|
tx.announce(vec![0u8; 1024 * 1024]).unwrap();
|
|
|
|
for listener in listeners {
|
|
black_box(listener.try_listen());
|
|
}
|
|
});
|
|
});
|
|
|
|
// Arc Clone
|
|
group.bench_with_input(BenchmarkId::new("arc_clone", n), n, |b, &n| {
|
|
b.iter(|| {
|
|
let (tx, announcement) = Announcement::new();
|
|
|
|
let mut listeners = Vec::new();
|
|
for _ in 0..n {
|
|
listeners.push(announcement.listener());
|
|
}
|
|
|
|
tx.announce(Arc::new(vec![0u8; 1024 * 1024])).unwrap();
|
|
|
|
for listener in listeners {
|
|
black_box(listener.try_listen());
|
|
}
|
|
});
|
|
});
|
|
}
|
|
group.finish();
|
|
}
|
|
|
|
// Complex type: Config with String, Vec, HashMap
|
|
#[derive(Clone, Debug)]
|
|
#[allow(dead_code)]
|
|
struct Config {
|
|
name: String,
|
|
tags: Vec<String>,
|
|
settings: HashMap<String, String>,
|
|
data: Vec<u8>,
|
|
}
|
|
|
|
impl Config {
|
|
fn new() -> Self {
|
|
let mut settings = HashMap::new();
|
|
settings.insert("key1".to_string(), "value1".to_string());
|
|
settings.insert("key2".to_string(), "value2".to_string());
|
|
settings.insert("key3".to_string(), "value3".to_string());
|
|
|
|
Config {
|
|
name: "MyConfig".to_string(),
|
|
tags: vec!["tag1".to_string(), "tag2".to_string(), "tag3".to_string()],
|
|
settings,
|
|
data: vec![0u8; 1024],
|
|
}
|
|
}
|
|
}
|
|
|
|
fn bench_complex_type(c: &mut Criterion) {
|
|
let mut group = c.benchmark_group("complex_type_config");
|
|
|
|
for n in [1, 10, 100, 500].iter() {
|
|
group.throughput(Throughput::Elements(*n as u64));
|
|
|
|
// Direct Clone
|
|
group.bench_with_input(BenchmarkId::new("direct_clone", n), n, |b, &n| {
|
|
b.iter(|| {
|
|
let (tx, announcement) = Announcement::new();
|
|
|
|
let mut listeners = Vec::new();
|
|
for _ in 0..n {
|
|
listeners.push(announcement.listener());
|
|
}
|
|
|
|
tx.announce(Config::new()).unwrap();
|
|
|
|
for listener in listeners {
|
|
black_box(listener.try_listen());
|
|
}
|
|
});
|
|
});
|
|
|
|
// Arc Clone
|
|
group.bench_with_input(BenchmarkId::new("arc_clone", n), n, |b, &n| {
|
|
b.iter(|| {
|
|
let (tx, announcement) = Announcement::new();
|
|
|
|
let mut listeners = Vec::new();
|
|
for _ in 0..n {
|
|
listeners.push(announcement.listener());
|
|
}
|
|
|
|
tx.announce(Arc::new(Config::new())).unwrap();
|
|
|
|
for listener in listeners {
|
|
black_box(listener.try_listen());
|
|
}
|
|
});
|
|
});
|
|
}
|
|
group.finish();
|
|
}
|
|
|
|
// Comparison benchmark showing the crossover point
|
|
fn bench_crossover_analysis(c: &mut Criterion) {
|
|
let mut group = c.benchmark_group("crossover_analysis");
|
|
|
|
// Test various type sizes to find where Arc becomes beneficial
|
|
let sizes = [4, 8, 16, 32, 64, 128, 256, 512];
|
|
|
|
for size in sizes.iter() {
|
|
group.throughput(Throughput::Bytes(*size as u64));
|
|
|
|
// Direct clone with 10 listeners
|
|
group.bench_with_input(
|
|
BenchmarkId::new("direct_10_listeners", size),
|
|
size,
|
|
|b, &size| {
|
|
b.iter(|| {
|
|
let (tx, announcement) = Announcement::new();
|
|
|
|
let mut listeners = Vec::new();
|
|
for _ in 0..10 {
|
|
listeners.push(announcement.listener());
|
|
}
|
|
|
|
let data = vec![0u8; size];
|
|
tx.announce(data).unwrap();
|
|
|
|
for listener in listeners {
|
|
black_box(listener.try_listen());
|
|
}
|
|
});
|
|
},
|
|
);
|
|
|
|
// Arc clone with 10 listeners
|
|
group.bench_with_input(
|
|
BenchmarkId::new("arc_10_listeners", size),
|
|
size,
|
|
|b, &size| {
|
|
b.iter(|| {
|
|
let (tx, announcement) = Announcement::new();
|
|
|
|
let mut listeners = Vec::new();
|
|
for _ in 0..10 {
|
|
listeners.push(announcement.listener());
|
|
}
|
|
|
|
let data = Arc::new(vec![0u8; size]);
|
|
tx.announce(data).unwrap();
|
|
|
|
for listener in listeners {
|
|
black_box(listener.try_listen());
|
|
}
|
|
});
|
|
},
|
|
);
|
|
}
|
|
group.finish();
|
|
}
|
|
|
|
criterion_group!(
|
|
benches,
|
|
bench_small_type,
|
|
bench_medium_type,
|
|
bench_large_type,
|
|
bench_complex_type,
|
|
bench_crossover_analysis,
|
|
);
|
|
criterion_main!(benches);
|