intern-mint 0.3.2

byte slice interning
Documentation
use std::{borrow::Borrow, collections::HashMap, hash::Hash, sync::LazyLock};

use criterion::{Criterion, criterion_group, criterion_main};
use intern_mint::BorrowedInterned;

include!("./random_strings_pool.rs");

#[inline]
fn use_generic<K, Q>(intern: fn(&str) -> K) -> u32
where
    K: Eq + Hash + Clone + Borrow<Q>,
    Q: Eq + Hash + ?Sized,
{
    let mut map = HashMap::<K, u32>::with_capacity(POOL.len());

    for i in 0..2 {
        for &s in POOL {
            let interned = intern(s);
            let value = map.entry(interned).or_default();
            *value += i;
        }
    }

    let mut sum = 0;

    for key in map.keys() {
        let key = key.clone();
        let borrowed = Borrow::<Q>::borrow(&key);
        sum += map.get(borrowed).copied().unwrap_or_default();
    }

    sum
}

fn use_intern_mint() -> u32 {
    use intern_mint::Interned;
    use_generic::<Interned, BorrowedInterned>(|o| Interned::from(o))
}

fn use_internment() -> u32 {
    use internment::ArcIntern;
    use_generic::<ArcIntern<String>, ArcIntern<String>>(|o| ArcIntern::from_ref(o))
}

fn use_intern_arc() -> u32 {
    use intern_arc::{HashInterner, InternedHash};
    static INTERN_ARC_POOL: LazyLock<HashInterner<str>> = LazyLock::new(Default::default);
    use_generic::<InternedHash<str>, InternedHash<str>>(|o| INTERN_ARC_POOL.intern_ref(o))
}

fn use_multithreaded(to_test: fn() -> u32) {
    let _data = rayon::broadcast(|_| to_test());
}

fn benchmark(c: &mut Criterion) {
    rayon::ThreadPoolBuilder::new()
        .num_threads(
            std::thread::available_parallelism()
                .map(|o| o.get())
                .unwrap_or(1),
        )
        .build_global()
        .unwrap();

    c.bench_function("intern-mint", |b| {
        b.iter(|| use_multithreaded(use_intern_mint))
    });

    c.bench_function("internment", |b| {
        b.iter(|| use_multithreaded(use_internment))
    });

    c.bench_function("intern-arc", |b| {
        b.iter(|| use_multithreaded(use_intern_arc))
    });
}

criterion_group! {
  name = benches;
  config = Criterion::default().sample_size(10000);
  targets = benchmark
}
criterion_main!(benches);