How fast is C++26’s std::hive?

Lobsters Hottest Tools

Summary

This article benchmarks the new C++26 std::hive container against std::vector and std::list, showing it has insertion costs about twice that of vector, iteration latency-bound like list, but better locality and erase performance for scattered erasures.

<p><a href="https://lobste.rs/s/jqydry/how_fast_is_c_26_s_std_hive">Comments</a></p>
Original Article
View Cached Full Text

Cached at: 08/03/26, 01:33 AM

# How fast is C++26’s std::hive? Source: [https://lemire.me/blog/2026/08/02/how-fast-is-c26s-stdhive/](https://lemire.me/blog/2026/08/02/how-fast-is-c26s-stdhive/) C\+\+26 adds a new container to the standard library:`std::hive`\. It is meant to occupy the ground between`std::vector`and`std::list`\. Like a vector, it keeps its elements in contiguous blocks of memory, so scanning it does not require you to chase a pointer for every element\. Like a list, it never moves an element once it has been inserted: your pointers, references and iterators stay valid, and you may erase any element in constant time without disturbing the others\. Internally, a hive is a linked list of blocks\. Each block carries a*skipfield*: a small integer per slot that tells the iterator how many erased slots to jump over\. No standard library ships`std::hive`yet to my knowledge\. Fortunately there is an implementation \([plf::hive](https://github.com/mattreecebentley/plf_hive)by Matt Bentley\) as a single header file that you can use today\. I use elements of type`uint64\_t`, GCC 16\.1 with`\-O3 \-march=native`, on an Intel Xeon Gold 6548N \(Emerald Rapids\), pinned to one core\. Numbers are nanoseconds per element, along with the cycles and instructions retired per element\. We start from an empty container and append a million values\. The container is then destroyed\. containerns/elementinstructions/element`std::vector`\(`reserve`\)0\.298\.0`std::vector`0\.818\.0`std::hive`1\.5716\.2`std::hive`\(`reserve`\)1\.7617\.0`std::list`14\.22220\.0A`std::list`needs one allocation per element, and glibc’s malloc and free together cost over 200 instructions per element\. It is an order of magnitude behind everyone else\. That is not news\. The interesting comparison is vector against hive\. A hive is about twice the cost of a vector, and it needs twice the instructions\. This is the price of the skipfield: every insertion writes an element*and*a skipfield entry, and maintains the block bookkeeping\. Note that calling`reserve`on a hive does not help in my experiments\. Next we iterate over the the container and sum the values\. containerns/elementcycles/elementinstructions/element`std::vector`0\.220\.781\.0`std::list`1\.515\.274\.0`std::hive`1\.776\.189\.0A hive iterates no faster than a linked list here, slightly slower, in fact, and about eight times slower than a vector\. The vector loop retires one instruction per element and finishes in 0\.78 cycles: the processor is executing several elements at once\. This is possible because the`std::vector`implementation benefits from autovectorization: the compiler recognizes that it can load several words at once in wide \(SIMD\)\. Further, it does not have to check the bitfield like the`std::hive`data structure\. We can check this\. Walk the same container with two independent iterators, one starting halfway in, and count the cost per element visited: containerone traversaltwo interleaved traversals`std::vector`0\.78 cycles0\.79 cycles`std::list`5\.27 cycles3\.02 cycles`std::hive`6\.18 cycles3\.10 cyclesThe vector does not care: it was already throughput\-bound\. The hive and the list get nearly twice as fast per element, because two independent chains can be in flight at once\. Hive iteration is latency\-bound, exactly like list iteration\. It merely has better locality\. That locality does show up when the data gets big\. At ten million elements the list falls apart while the hive holds steady: container100K1M10M`std::vector`0\.080\.220\.32`std::list`1\.481\.513\.51`std::hive`1\.761\.771\.96Erasing is what a hive is for, so it would be unfair not to look\. I erase half the elements at scattered positions using`std::remove\_if`: containerns per original element`std::hive`2\.1`std::vector`3\.0`std::list`77\.4The hive wins, but by less than you might expect, and at ten million elements the ordering reverses \(1\.3 ns for the vector against 2\.5 for the hive\)\.`std::remove\_if`is a single streaming pass, and streaming passes are cheap\. Of course the vector moved every surviving element and invalidated every pointer into it, which is precisely what a hive promises not to do\. Memory, measured by asking glibc how many bytes it has handed out, per live element: containerafter buildingafter`shrink\_to\_fit``std::vector`8\.48\.0`std::hive`9\.49\.4`std::list`32\.0A hive costs about a byte per element over a vector, for a payload of eight bytes, when the vector is packed tight\. A list costs more due to the overhead of the linked list\. A vector built by`push\_back`has a capacity that typically exceeds its size\. Thus even if you have 8\-byte entries, you will use, on average, more than 8 bytes per entry even for large vectors\. You can recover the excess capacity with the`shrink\_to\_fit`method\. What should we conclude? The`std::hive`data structure is not a faster vector\. But it is a much better`std::list`\. It gives you the same guarantees that make people reach for a list, stable references, cheap erasure anywhere, while using less memory\. [My source code is available](https://github.com/lemire/Code-used-on-Daniel-Lemire-s-blog/tree/master/2026/08/02)\.

Similar Articles

C++26 Shipped a SIMD Library Nobody Asked For

Lobsters Hottest

The article criticizes the new std::simd library in C++26, arguing it is slower than scalar loops, compiles slowly, and is outperformed by auto-vectorizers and alternative libraries like Google Highway, questioning its value after a decade-long standardization process.

The C++ Standard Library Has Been Walking Itself Back for Fifteen Years, and the Receipts Are Public

Lobsters Hottest

A detailed catalogue of C++ standard library features that have been formally deprecated, informally discouraged, or are effectively broken but cannot be fixed due to ABI constraints, spanning from C++11 to C++26. The article argues a consistent pattern of the C++ committee shipping replacements for its own features, including a benchmark showing 58x P99 latency difference between Rust and C++ standard library containers.

C++26: Standard library hardening

Lobsters Hottest

C++26 is introducing standardized library hardening to catch common undefined behavior (like out-of-bounds access) at runtime, based on Google's production experience showing a mere 0.30% performance overhead and a 30% reduction in segmentation faults.