orderbook matches buy and sell orders the way an exchange does: best price first, and first come, first served at the same price. It supports limit, market, cancel, reduce and modify orders. It is header-only C++20 with no dependencies, and the hot path has no heap allocation, no virtual calls and no floating point.
Two ladders, one benchmark
The book stores each side's price levels in a "ladder", and there are two versions behind the same template parameter:
ArrayLadder: a flat array with one slot per price tick, plus a bitmap of non-empty levels. Finding the next best price scans 64 levels per instruction.
MapLadder: a std::map keyed by price.
On 5M operations (70% add, 27% cancel, 3% market) with about 10k resting orders over about 170 price levels, ArrayLadder runs at about 94M ops/s against about 57M for MapLadder, with a market-order p99 of 42 ns against 84 ns.
Why the gap grows
At about 170 levels, the whole map fits in L1 cache, so it holds up well. Spread the same orders over more price levels and the tree gets deeper and falls out of cache, while the array's direct indexing barely changes:
The array ladder is 1.5x faster at 40 levels and 3.8x faster at about 6,000. The trade-off is that it needs a bounded price band (65,536 ticks by default).
Built with C++20, CMake, and AddressSanitizer and UndefinedBehaviorSanitizer for testing.