OA foundation benchmark

A from-scratch C++ foundation for OA, now measured across containers, formatting, algorithms, ownership, runtime primitives, and the host-memory operations that moved into the same foundation surface.

v0.7.23 engineering checkpoint281 foundation Release testsMeasured 2026-08-28

Independent foundation, competitive on its real workloads

OA's foundation is an original implementation designed around OA's admitted product workloads. It was written from scratch; it is not an STL source port, compatibility layer, or renamed wrapper surface. The result is not a small synthetic win hidden behind one score: 27 of 32 recorded foundation cases are at parity or ahead on this host, while the remaining overheads stay visible below.

Evidence sliceCurrent result
Foundation primitives32 cases spanning runtime calls, values, text, containers, algorithms, and ownership
Hash containersInsertion used 34.1–35.1% of host time; collision cases used 63.4–66.1%
Thread-safe shared ownershipMake and copy/release reached parity after thread creation
Brace formattingInteger, padded/bool, and fixed-float cases were faster; the mixed record reached parity
Dynamic small copy8 B and 32 B used 49.8% and 66.3% of libc latency
Cache-cold streamingNine stable wins from 1 KiB through 4 MiB; best row used 65.3% of libc time
Correctness281 foundation Release tests; focused formatting/output sanitizer passes

This is fixed-host engineering evidence, not a universal performance claim. OA still uses explicit OS, compiler, C-runtime, and Vulkan adapters where they are the correct boundary. The separate linked-binary and full platform-independence matrix remains qualification work.

Foundation, not oa::std

Std is the short navigation label, not a namespace. The public vocabulary lives directly under oa: oa::Vector, oa::String, oa::Result, oa::HashMap, and oa::SharedPtr. The former pre-1.0 oa::Vec spelling has been removed.

SurfaceImplemented workContract
Values and failureFixed-width scalars, Status, Result, Optional, Variant, PairExplicit failure and bounded composition
Storage and viewsArray, Span, Vector, StringView, StringOA-owned layouts and lifetime rules
Lookup and algorithmsHashMap, HashSet, hashing, sort, find, fill, min/max/clampMeasured product-owned use cases
Formatting and outputformat, print, write, explicit streams and flushBounded brace formatting and recoverable host I/O
Ownership and callablesUniquePtr, SharedPtr, WeakPtr, callback and owned functionsUnique ownership remains preferred
Runtime and memoryAtomics, locks, threads, clocks, virtual memory, byte operations, paths, files, CLI, UnicodePortable contracts over private adapters

Measured protocol

FieldRecorded value
EvidenceFixed-host engineering comparisons measured through 2026-08-28
ToolchainClang 22.1.8; glibc 2.44; Linux 7.1.8-arch1-3
HostIntel Core i5-1145G7; process pinned to CPU 2
Formatting hostSame fixed host; formatting campaign pinned separately to CPU 3
Power and thermalsintel_pstate powersave; 400 MHz–4.4 GHz; package 70 C before and 66 C after
Formatting powerAC power; intel_pstate powersave governor; balanced power profile
Foundation workload32,768 general items; 8,192 hash items
Formatting workload32,768 items; five warmups; 21 alternating samples in each of seven fresh processes
Memory workloadReusable dynamic buffers plus cache-cold 256 MiB rotating arenas
Sampling5 warmups; 21 rotating or alternating OA/host samples per fresh process
EstimatorMedian of seven per-process ratios; range is complete min–max
CorrectnessIndependent preflight and checksum before reporting every measured pair

Every ratio is OA latency divided by its equivalent host operation. Below 1.0 favors OA. A complete process range crossing 1.0 is treated as parity, even when the median falls on one side.

Foundation results

The full result is split by behavior so the table remains readable without collapsing the campaign into an average. First are runtime calls, bounded values, text views, and algorithms.

CaseMedian OA / hostProcess rangeRecorded result
Steady clock1.026×1.016–1.029×2.6% overhead
Mutex lock / unlock1.193×1.167–1.225×19.3% overhead
Array indexed read1.001×0.998–1.002×Parity
Span traversal1.000×0.999–1.003×Parity
Atomic relaxed add1.000×1.000–1.059×Parity median
Optional lifecycle0.999×0.998–1.001×Parity
Algorithm sort1.003×0.993–1.011×Parity
Find / count algorithms0.939×0.938–0.939×6.1% less time
C strlen / byte0.994×0.981–1.039×Parity
C strchr miss / byte1.004×0.985–1.006×Parity
C strcmp equal / byte1.000×0.993–1.004×Parity
C strncmp equal / byte1.009×0.999–1.013×Parity to +0.9%
StringView find / byte1.009×0.984–1.016×Parity to +0.9%
Scalar sin / tanh1.000×0.972–1.069×Parity median

The checked clock and mutex ABI boundaries retain measurable call overhead. Sort is at parity; find/count is a stable win. These results keep checks and failure semantics enabled.

Sequences, text, variants, and callables

CaseMedian OA / hostProcess rangeRecorded result
Vector · reserved scalar push1.593×1.589–1.701×59.3% overhead
Vector · geometric growth1.062×1.029–1.132×6.2% overhead
Vector · bulk append / element1.000×0.998–1.001×Parity
String · reserved push0.923×0.906–0.996×7.7% less time
String · geometric growth0.876×0.865–0.892×12.4% less time
String · bulk append / byte1.004×1.001–1.012×Parity to +0.4%
Variant emplace / visit1.001×0.999–1.002×Parity
Function invoke1.000×0.999–1.000×Parity

Vector bulk append is the intended high-throughput path and is at parity. The reserved single-element loop exposes an optimizer control-flow gap rather than hiding it behind the bulk result. String wins in both reserved-push and geometric-growth workloads.

Lookup and ownership

CaseMedian OA / hostProcess rangeRecorded result
HashMap insertion0.341×0.309–0.346×65.9% less time
HashSet insertion0.351×0.278–0.356×64.9% less time
HashMap successful find0.879×0.861–0.882×12.1% less time
HashSet successful find0.751×0.675–0.762×24.9% less time
HashMap collision insertion0.661×0.628–0.760×33.9% less time
HashMap collision miss0.634×0.601–0.647×36.6% less time
SharedPtr make / release · initial process state0.999×0.785–1.042×Parity; noisy
SharedPtr copy / release · initial process state2.627×2.512–2.701×Host shortcut
SharedPtr make / release · after thread creation0.968×0.944–1.010×Parity in spread
SharedPtr copy / release · after thread creation1.003×0.988–1.017×Parity

The hash tables are the largest general-foundation win. Shared ownership needs one explicit qualification: on this glibc/libstdc++ host, copy/release avoids atomic reference-count work until a thread has existed. OA keeps thread-safe counts in both process states. Once the host uses its thread-safe path, OA make/release and copy/release are at parity.

Brace formatting and record output

oa::format, oa::print, and oa::write use a bounded, literal brace-format syntax familiar from Python and {fmt}. This is OA's deliberately smaller dialect, not a source port or a claim of complete std::format or {fmt}compatibility. The benchmark compares identical formatted output with the toolchain's std::format.

Format.cpp

1#include <oa/core/std/print.h>
2
3const oa::String message = oa::format("epoch={} loss={:.4f}", epoch, loss);
4OA_RETURN_IF_ERROR(oa::print("epoch={} loss={:.4f}", epoch, loss));
5OA_RETURN_IF_ERROR(oa::print(oa::PrintStream::Error, "failed: {}", reason));
6OA_RETURN_IF_ERROR(oa::write("\rprogress={:.1f}%", percent));
7OA_RETURN_IF_ERROR(oa::flush());
8
CaseMedian OA / hostProcess rangeRecorded result
Signed decimal integer0.589×0.577–0.603×41.1% less latency
Padded hex + bool0.668×0.661–0.688×33.2% less latency
Fixed-precision float0.913×0.901–0.919×8.7% less latency
Padded hex + bool + float1.003×0.975–1.011×Parity in spread

Each row is the median paired OA/standard-library latency ratio across seven fresh processes. Integer formatting used 58.9% of host time, padded hexadecimal plus boolean used 66.8%, and fixed-precision floating point used 91.3%. The mixed record's 1.003× median crosses parity over its complete 0.975–1.011× range, so it is recorded as parity, not a regression.

ContractBehavior
Format programCharacter-array literal with sequential {} or {:spec} fields and escaped braces
Supported valuesOA strings/views, C strings, bool, character, integers, enums, float/double, pointers, and values with toString()
Specifier subsetFill/alignment, sign, alternate form, zero padding, bounded width/precision, integer bases, and f/e/g floats
Outputprint adds one newline; write adds none; Out/Error streams are explicit; flush is never implicit
FailureInvalid format programs fail the always-on contract; host write and flush failures return Status
BoundsWidth is capped at 1 MiB and complete output at 16 MiB; floating conversion is pinned to the C numeric locale

The accepted optimization keeps those checks intact: fixed literal syntax can fold at the call site, records through 128 bytes use bounded inline staging, and floating conversion writes directly into checked caller storage. No unchecked formatter, precision change, locale mutation, or hosted C++ dependency was added to obtain the result.

Host memory is now part of the foundation

The old raw-assembly memory path was removed. OA now uses legal exact-bounds compiler copies for dynamic blocks through 256 B, tuned platform operations where they remain best, and a separate oa::memcpyStream policy only when the destination will not be consumed soon. That separation keeps ordinary copy behavior predictable while admitting cache-aware wins for one-way uploads.

Dynamic copy with reusable buffers

CaseMedian OA / hostProcess rangeRecorded result
8 B0.498×0.448–0.540×50.2% less latency
32 B0.663×0.632–0.679×33.7% less latency
256 B0.968×0.864–1.085×Parity in spread
4 KiB1.059×1.018–1.088×Dispatcher overhead
64 KiB1.003×1.001–1.024×Parity
1 MiB1.007×0.984–1.045×Parity in spread
16 MiB1.022×1.003–1.038×Near parity
64 MiB1.025×0.910–1.066×Parity in spread

Fixed compile-time OA and compiler-copy rows reduce to the same instructions. The dynamic dispatcher is retained for the stable 8 B and 32 B gains; large ordinary copies continue through libc and return to parity.

Cache-cold one-way streaming

The sweep rotates chunks through separate 256 MiB source and destination arenas—32 times the host's 8 MiB last-level cache. Each ratio cell includes the median followed by the complete seven-process range; throughput columns are absolute medians.

ChunkOrdinary OA / libcStream OA / libclibcOA stream
256 B0.922× · 0.891–0.9910.940× · 0.904–1.0257.641 GB/s7.959 GB/s
512 B1.007× · 0.975–1.0551.016× · 0.975–1.0548.358 GB/s8.571 GB/s
1 KiB1.012× · 0.958–1.1210.855× · 0.808–0.9848.809 GB/s10.053 GB/s
2 KiB1.006× · 0.989–1.0360.653× · 0.608–0.7317.396 GB/s11.300 GB/s
4 KiB1.000× · 0.987–1.0240.955× · 0.818–1.03711.168 GB/s11.693 GB/s
8 KiB1.006× · 0.971–1.0300.882× · 0.826–0.90010.871 GB/s12.467 GB/s
16 KiB0.992× · 0.977–1.0190.853× · 0.824–0.87610.937 GB/s13.053 GB/s
64 KiB1.008× · 0.975–1.0440.792× · 0.765–0.85610.880 GB/s13.587 GB/s
256 KiB0.990× · 0.973–1.0300.861× · 0.787–0.90410.925 GB/s12.925 GB/s
1 MiB1.000× · 0.985–1.0170.831× · 0.809–0.86010.798 GB/s13.023 GB/s
2 MiB0.988× · 0.953–1.0420.839× · 0.769–0.85711.248 GB/s13.348 GB/s
4 MiB1.015× · 0.963–1.0360.829× · 0.780–0.88211.129 GB/s13.492 GB/s
8 MiB0.982× · 0.921–1.0340.972× · 0.906–1.02316.106 GB/s16.255 GB/s
16 MiB0.996× · 0.980–1.1360.990× · 0.918–1.07816.170 GB/s16.284 GB/s
64 MiB0.989× · 0.973–1.0710.993× · 0.955–1.07815.735 GB/s15.819 GB/s

The qualified x86 non-temporal window runs from 1 KiB through 4 MiB. Nine rows in that window are stable wins; 2 KiB is best at 0.653×. From 64 KiB through 4 MiB, streaming uses 79.2–83.9% of libc time except the 256 KiB row at 86.1%. The 4 KiB range crosses parity and is classified as flat. Below and above the window, fallback restores parity.

Equality, ordering, and overlap

Each cell reports the median OA / libc ratio followed by its complete process range.

Operation8 B256 B4 KiB64 KiB
memEqual · equal1.714× · 1.593–2.6661.367× · 1.360–1.4991.187× · 1.051–1.1960.639× · 0.638–0.732
memEqual · early mismatch1.629× · 1.629–1.6400.778×0.787× · 0.779–0.8430.894× · 0.824–1.033
memEqual · late mismatch1.629× · 1.629–1.6301.058× · 1.000–1.0791.207× · 1.064–1.2500.645× · 0.643–0.713
memEqualConstantTime · equal1.617× · 1.571–1.7131.402× · 1.363–1.5480.563× · 0.554–0.6030.664× · 0.592–0.665

memcmp and both overlapping memmove directions measured at a1.000×median at all four representative sizes. Constant-work equality has a stricter security contract than libc's early-exit comparison, so its result is not presented as a semantic speedup. Platform fill and zero also remain faster than the rejected hand-vectorized paths.

Measured decisions, including the rejected ones

DecisionWhy it remains
Adaptive streaming windowKeeps nine stable medium-size wins and restores parity outside the qualified range
Ordinary platform copy for large buffersNo durable OA advantage was measured for the general copy contract
Thread-safe SharedPtr countsPortable ownership semantics do not depend on undocumented process-global thread state
Checked clock and mutex boundariesFailure and ABI behavior remain explicit despite measured call overhead
Rejected force-all non-temporal copyRegressed 256 B to 1.636× and 8–64 MiB to about 1.14×
Rejected AVX-512 eight-vector unrollSeven processes established no stable improvement over four vectors
Rejected unchecked or non-atomic shortcutsThey weakened safety, portability, or failure contracts

Correctness before timing

GateCovered contract
Containers and algorithmsCollision, tombstone, rehash, adversarial order, aliasing, growth, throwing relocation, and lifetime
Ownership and concurrencyReference-count bounds plus concurrent final strong and weak release
MemoryFull content, overlap, alignment, tails, guard bytes, ordinary equality, and fixed-length secret equality
Earlier foundation checkpointAll 271 focused Release tests passed
Formatting checkpointAll 281 foundation Release tests passed; 15 focused formatting/output tests passed under ASAN+LSAN and fail-fast UBSAN
Sanitizers272 tests passed under combined ASAN+UBSAN and under TSan; no finding suppressed
Coverage checkpoint77.72% lines, 78.24% functions, and 63.95% branches at the 4.29 header checkpoint

Evidence boundary

This checkpoint qualifies one compiler, host library, machine, workload, and date. It does not establish cross-platform superiority, complete hostile-input resilience, or linked-binary independence from libstdc++ or libc++. YAML, VMA, private third-party link closure, no-exception/no-RTTI builds, longer fuzzing, allocator-fault campaigns, and the full compiler and platform matrix retain their own qualification gates.

Reproduce

Use a fixed power policy and record thermal conditions. Release comparison requires immutable commits, rotating or alternating samples, median and spread, and passing correctness gates. A single process is useful for profiling, not release evidence.

Foundation terminal

cmake --build build/release --target BenchStd TestOaStd -j
ctest --test-dir build/release -R '^TestOaStd$' --output-on-failure
taskset -c 2 ./bin/release/test/core/std/benchStd \
--items 32768 --warmups 5 --samples 21
# Formatting evidence was recorded separately on CPU 3.
taskset -c 3 ./bin/release/test/core/std/benchStd \
--items 32768 --warmups 5 --samples 21
cmake --build build/release --target BenchMemory TestMemory -j
taskset -c 2 ./bin/release/test/core/memory/benchMemory --quick --copy
taskset -c 2 ./bin/release/test/core/memory/benchMemory --quick --primitives
taskset -c 2 ./bin/release/test/core/memory/benchMemory --streaming
# Run each campaign as at least seven fresh processes.