Testing and Benchmarks
Relevant source files
This document covers the testing infrastructure and performance evaluation framework for the allocator crate. The testing system validates correctness and measures performance across all supported allocator implementations through comprehensive integration tests and benchmarks.
For information about specific allocator implementations being tested, see Allocator Implementations. For details on individual test scenarios, see Integration Tests and Performance Benchmarks.
Testing Infrastructure Overview
The allocator crate provides a comprehensive testing framework that validates both correctness and performance across all allocator implementations. The testing infrastructure consists of integration tests and performance benchmarks that exercise the allocators through realistic usage patterns.
Testing Architecture
flowchart TD
subgraph subGraph3["Test Execution"]
RUN_TEST["run_test()"]
MEMORY_POOL["MemoryPool"]
CRITERION["criterion_benchmark()"]
end
subgraph subGraph2["Allocator Implementations Under Test"]
SYS_ALLOC["std::alloc::System"]
BUDDY_RC["AllocatorRc"]
SLAB_RC["AllocatorRc"]
TLSF_RC["AllocatorRc"]
end
subgraph subGraph1["Test Functions"]
TEST_VEC["test_vec()"]
TEST_VEC2["test_vec2()"]
TEST_BTREE["test_btree_map()"]
TEST_ALIGN["test_alignment()"]
BENCH_VEC_PUSH["vec_push()"]
BENCH_VEC_RAND["vec_rand_free()"]
BENCH_BTREE["btree_map()"]
end
subgraph subGraph0["Test Infrastructure"]
INTEGRATION["tests/allocator.rs"]
BENCHMARKS["benches/collections.rs"]
UTILS["benches/utils/mod.rs"]
end
BENCHMARKS --> BENCH_BTREE
BENCHMARKS --> BENCH_VEC_PUSH
BENCHMARKS --> BENCH_VEC_RAND
BENCHMARKS --> CRITERION
BENCHMARKS --> MEMORY_POOL
INTEGRATION --> TEST_ALIGN
INTEGRATION --> TEST_BTREE
INTEGRATION --> TEST_VEC
INTEGRATION --> TEST_VEC2
RUN_TEST --> MEMORY_POOL
TEST_VEC --> BUDDY_RC
TEST_VEC --> SLAB_RC
TEST_VEC --> SYS_ALLOC
TEST_VEC --> TLSF_RC
TEST_VEC2 --> BUDDY_RC
TEST_VEC2 --> SLAB_RC
TEST_VEC2 --> SYS_ALLOC
TEST_VEC2 --> TLSF_RC
UTILS --> MEMORY_POOL
The testing architecture separates integration testing from performance benchmarking while using consistent test scenarios across both. Each allocator implementation is tested through the same set of operations to ensure behavioral consistency and enable performance comparison.
Sources: tests/allocator.rs(L1 - L144) benches/collections.rs(L1 - L102)
Test Environment Configuration
The testing framework uses a standardized memory pool configuration to ensure consistent and reproducible results across all test runs.
| Configuration | Value | Purpose |
|---|---|---|
| POOL_SIZE | 128 MB | Standard memory pool size for custom allocators |
| Memory Layout | 4096-byte aligned | Ensures proper page alignment for testing |
| Random Seed | 0xdead_beef | Deterministic randomization for benchmarks |
| Sample Size | 10 iterations | Benchmark measurement accuracy |
flowchart TD
subgraph subGraph1["Allocator Initialization"]
BUDDY_INIT["BuddyByteAllocator::new()"]
SLAB_INIT["SlabByteAllocator::new()"]
TLSF_INIT["TlsfByteAllocator::new()"]
RC_WRAPPER["AllocatorRc::new(allocator, pool)"]
end
subgraph subGraph0["Memory Pool Setup"]
ALLOC_LAYOUT["Layout::from_size_align(POOL_SIZE, 4096)"]
ALLOC_PTR["std::alloc::alloc_zeroed()"]
SLICE_POOL["core::slice::from_raw_parts_mut()"]
end
ALLOC_LAYOUT --> ALLOC_PTR
ALLOC_PTR --> SLICE_POOL
BUDDY_INIT --> RC_WRAPPER
SLAB_INIT --> RC_WRAPPER
SLICE_POOL --> RC_WRAPPER
TLSF_INIT --> RC_WRAPPER
Sources: tests/allocator.rs(L11) tests/allocator.rs(L87 - L95) benches/collections.rs(L16)
Test Scenarios and Methodology
The testing framework implements several key scenarios that exercise different allocation patterns and stress test the allocators under various conditions.
Core Test Scenarios
| Test Function | Purpose | Parameters | Stress Pattern |
|---|---|---|---|
| test_vec | Vector growth and sorting | 3M elements | Sequential allocation |
| test_vec2 | Fragmentation testing | 30K/7.5K blocks | Random deallocation |
| test_btree_map | Complex data structures | 50K operations | Mixed insert/remove |
| test_alignment | Alignment validation | 50 iterations | Variable size/alignment |
Vector Operation Testing
The test_vec function validates basic allocation behavior through vector operations that require continuous memory growth and reallocation.
sequenceDiagram
participant test_vec as "test_vec()"
participant Vecu32 as "Vec<u32>"
participant Allocator as "Allocator"
test_vec ->> Vecu32: "Vec::with_capacity_in(n, alloc)"
loop "n iterations"
test_vec ->> Vecu32: "push(random_u32)"
Vecu32 ->> Allocator: "allocate/reallocate"
end
test_vec ->> Vecu32: "sort()"
test_vec ->> test_vec: "verify sorted order"
test_vec ->> Vecu32: "drop()"
Vecu32 ->> Allocator: "deallocate"
Sources: tests/allocator.rs(L13 - L22) benches/collections.rs(L18 - L24)
Fragmentation Testing
The test_vec2 and vec_rand_free functions specifically target memory fragmentation by creating many small allocations and then randomly deallocating them.
flowchart TD
subgraph subGraph1["Test Parameters"]
PARAMS1["25K blocks × 64 bytes"]
PARAMS2["7.5K blocks × 520 bytes"]
RNG["SmallRng::seed_from_u64(0xdead_beef)"]
end
subgraph subGraph0["Fragmentation Test Flow"]
ALLOCATE["Allocate n blocks of blk_size"]
SHUFFLE["Shuffle deallocation order"]
DEALLOCATE["Randomly deallocate blocks"]
VERIFY["Verify allocator state"]
end
ALLOCATE --> SHUFFLE
DEALLOCATE --> VERIFY
PARAMS1 --> ALLOCATE
PARAMS2 --> ALLOCATE
RNG --> SHUFFLE
SHUFFLE --> DEALLOCATE
Sources: tests/allocator.rs(L24 - L40) benches/collections.rs(L26 - L44)
Alignment and Layout Testing
The test_alignment function validates that allocators properly handle various size and alignment requirements, which is critical for compatibility with different data types.
Sources: tests/allocator.rs(L63 - L85)
Performance Measurement Framework
The benchmark suite uses the criterion crate to provide statistically rigorous performance measurements across all allocator implementations.
Benchmark Execution Flow
flowchart TD
subgraph subGraph2["Benchmark Functions"]
VEC_PUSH["vec_push_3M"]
VEC_RAND1["vec_rand_free_25K_64"]
VEC_RAND2["vec_rand_free_7500_520"]
BTREE["btree_map_50K"]
end
subgraph subGraph1["Allocator Testing Matrix"]
SYSTEM["bench(c, 'system', std::alloc::System)"]
TLSF["bench(c, 'tlsf', AllocatorRc)"]
SLAB["bench(c, 'slab', AllocatorRc)"]
BUDDY["bench(c, 'buddy', AllocatorRc)"]
end
subgraph subGraph0["Benchmark Setup"]
POOL_INIT["MemoryPool::new(POOL_SIZE)"]
CRITERION["Criterion::default()"]
BENCH_GROUP["benchmark_group(alloc_name)"]
end
BENCH_GROUP --> VEC_PUSH
CRITERION --> BENCH_GROUP
POOL_INIT --> BUDDY
POOL_INIT --> SLAB
POOL_INIT --> SYSTEM
POOL_INIT --> TLSF
SYSTEM --> BTREE
SYSTEM --> VEC_PUSH
SYSTEM --> VEC_RAND1
SYSTEM --> VEC_RAND2
Sources: benches/collections.rs(L63 - L98)
Benchmark Scenarios
The benchmark suite measures performance across scenarios that represent common real-world allocation patterns:
| Benchmark | Operation Count | Block Size | Pattern Type |
|---|---|---|---|
| vec_push_3M | 3,000,000 pushes | Variable | Sequential growth |
| vec_rand_free_25K_64 | 25,000 blocks | 64 bytes | Random fragmentation |
| vec_rand_free_7500_520 | 7,500 blocks | 520 bytes | Large block fragmentation |
| btree_map_50K | 50,000 operations | Variable | Complex data structure |
Sources: benches/collections.rs(L65 - L77)
Running Tests and Interpreting Results
Integration Test Execution
Integration tests are executed using standard Rust testing tools and validate allocator correctness across all implementations:
# Run all integration tests
cargo test
# Run tests for specific allocator
cargo test buddy_alloc
cargo test slab_alloc
cargo test tlsf_alloc
cargo test system_alloc
Each test function follows the pattern {allocator}_alloc() and executes the complete test suite against that allocator implementation.
Sources: tests/allocator.rs(L97 - L143)
Benchmark Execution
Performance benchmarks are run using the criterion framework, which provides detailed statistical analysis:
# Run all benchmarks
cargo bench
# Generate HTML report
cargo bench -- --output-format html
The benchmark results compare allocator performance against the system allocator baseline, providing insights into:
- Allocation speed for different patterns
- Memory fragmentation behavior
- Overhead of custom allocator implementations
Sources: benches/collections.rs(L100 - L101)