Skip to main content

Crate malloc_bench_rs

Crate malloc_bench_rs 

Source
Expand description

malloc-bench-rs — portable, generic-over-GlobalAlloc benchmark harness.

Run larson (server churn) + mstress (alloc-then-free batches) workloads against ANY std::alloc::GlobalAlloc, get aggregate ops/sec. Pre-spawns worker threads, runs a fixed op budget per worker, times the steady-state region (criterion-style per-iter timing mis-measures MT workloads — thread spawn inside the timed closure dominates; we avoid that).

§Design

Two workloads, both reporting aggregate ops/sec (an op = one alloc+free pair) over a fixed operation budget measured with Instant::elapsed:

  • larson — server-churn: each thread keeps a working set of live slots; each step frees a random slot and allocates a new random-size block into it. Periodically a block is handed off cross-thread.
  • mstress — rounds of “fill a vector of mixed blocks → free half in random order → refill → free all”; a fraction freed cross-thread.

Cross-thread handoff is leak/UAF-free by construction: every allocated block is freed exactly once, by exactly one thread. A handed-off block is moved out of the producer’s bookkeeping (its slot is set empty) before being sent; the consumer drains its mailbox and frees each received block once. At the end every thread frees its own remaining live blocks, then drains any final mailbox contents — so nothing is dropped on the floor and nothing is freed twice.

§Determinism

A dependency-free xorshift64 PRNG with a fixed per-thread seed, so runs are reproducible. No external rand crate is required.

§No #[global_allocator]

The harness calls GlobalAlloc::alloc/dealloc trait methods directly — it never sets #[global_allocator]. Your allocator does not need to be registered globally; you can benchmark several allocators in one binary.

§Example

use malloc_bench_rs::{run, Config, Workload};
use std::alloc::System;

let cfg = Config {
    threads: 2,
    steps_per_thread: 10_000,
    working_set: 128,
    mstress_blocks: 64,
};
let ops = run(Workload::Larson, &cfg, || System);
assert!(ops > 0.0, "expected non-zero ops/sec");

Structs§

Config
Configuration for a single benchmark run.

Enums§

Workload
Workload selector.

Functions§

run
Run one workload × allocator × thread-count and return aggregate ops/sec.
sweep
Run a thread-count sweep for one workload × allocator.