vecpool 0.1.0

Thread-local pool of reusable Vec buffers with cross-type reuse
Documentation
use criterion::{Criterion, criterion_group, criterion_main};
use std::hint::black_box;

fn bench_basic(c: &mut Criterion) {
    // Warm up pool
    drop(vecpool::get::<u32>());

    c.bench_function("get_drop_u32", |b| {
        b.iter(|| {
            let v = vecpool::get::<u32>();
            black_box(&v);
        });
    });

    c.bench_function("vec_new_drop_u32", |b| {
        b.iter(|| {
            let v: Vec<u32> = Vec::new();
            black_box(&v);
        });
    });

    c.bench_function("get_push100_drop", |b| {
        b.iter(|| {
            let mut v = vecpool::get::<u32>();
            for i in 0..100 {
                v.push(black_box(i));
            }
            black_box(&v);
        });
    });

    c.bench_function("vec_new_push100_drop", |b| {
        b.iter(|| {
            let mut v: Vec<u32> = Vec::new();
            for i in 0..100 {
                v.push(black_box(i));
            }
            black_box(&v);
        });
    });
}

fn bench_element_sizes(c: &mut Criterion) {
    // Warm up each lane
    drop(vecpool::get::<u8>());
    drop(vecpool::get::<u64>());
    drop(vecpool::get::<[u8; 1024]>());

    c.bench_function("get_push100_drop_u8", |b| {
        b.iter(|| {
            let mut v = vecpool::get::<u8>();
            for i in 0..100 {
                v.push(black_box(i));
            }
            black_box(&v);
        });
    });

    c.bench_function("get_push100_drop_u64", |b| {
        b.iter(|| {
            let mut v = vecpool::get::<u64>();
            for i in 0..100u64 {
                v.push(black_box(i));
            }
            black_box(&v);
        });
    });

    c.bench_function("get_push100_drop_1kb", |b| {
        b.iter(|| {
            let mut v = vecpool::get::<[u8; 1024]>();
            for _ in 0..100 {
                v.push(black_box([0u8; 1024]));
            }
            black_box(&v);
        });
    });
}

fn bench_multi_lane(c: &mut Criterion) {
    // Warm up multiple lanes
    drop(vecpool::get::<u8>());
    drop(vecpool::get::<u16>());
    drop(vecpool::get::<u32>());
    drop(vecpool::get::<u64>());

    c.bench_function("get_drop_4_lanes_roundrobin", |b| {
        b.iter(|| {
            black_box(vecpool::get::<u8>());
            black_box(vecpool::get::<u16>());
            black_box(vecpool::get::<u32>());
            black_box(vecpool::get::<u64>());
        });
    });
}

fn bench_pool_depth(c: &mut Criterion) {
    // Fill the u32 lane with 100 buffers
    let mut vecs: Vec<_> = (0..100)
        .map(|_| {
            let mut v = vecpool::get::<u32>();
            v.push(1); // force allocation
            v
        })
        .collect();
    // Return them all to pool
    vecs.clear();

    c.bench_function("get_drop_deep_pool_100", |b| {
        b.iter(|| {
            let v = vecpool::get::<u32>();
            black_box(&v);
        });
    });

    // Drain the pool back to 1
    let mut drain: Vec<_> = (0..99).map(|_| vecpool::get::<u32>()).collect();
    drain.clear();
}

fn bench_multiple_outstanding(c: &mut Criterion) {
    c.bench_function("get5_use_drop_varied_order", |b| {
        b.iter(|| {
            let mut v1 = vecpool::get::<u32>();
            let mut v2 = vecpool::get::<u32>();
            let mut v3 = vecpool::get::<u32>();
            let mut v4 = vecpool::get::<u32>();
            let mut v5 = vecpool::get::<u32>();
            v1.push(black_box(1));
            v2.push(black_box(2));
            v3.push(black_box(3));
            v4.push(black_box(4));
            v5.push(black_box(5));
            drop(v3);
            drop(v1);
            drop(v5);
            drop(v2);
            drop(v4);
        });
    });

    c.bench_function("vec_new5_use_drop_varied_order", |b| {
        b.iter(|| {
            let mut v1: Vec<u32> = Vec::new();
            let mut v2: Vec<u32> = Vec::new();
            let mut v3: Vec<u32> = Vec::new();
            let mut v4: Vec<u32> = Vec::new();
            let mut v5: Vec<u32> = Vec::new();
            v1.push(black_box(1));
            v2.push(black_box(2));
            v3.push(black_box(3));
            v4.push(black_box(4));
            v5.push(black_box(5));
            drop(v3);
            drop(v1);
            drop(v5);
            drop(v2);
            drop(v4);
        });
    });
}

criterion_group!(
    benches,
    bench_basic,
    bench_element_sizes,
    bench_multi_lane,
    bench_pool_depth,
    bench_multiple_outstanding
);
criterion_main!(benches);