uploaded current status
After Width: | Height: | Size: 36 KiB |
After Width: | Height: | Size: 37 KiB |
After Width: | Height: | Size: 40 KiB |
After Width: | Height: | Size: 49 KiB |
After Width: | Height: | Size: 37 KiB |
After Width: | Height: | Size: 35 KiB |
After Width: | Height: | Size: 40 KiB |
After Width: | Height: | Size: 45 KiB |
After Width: | Height: | Size: 38 KiB |
After Width: | Height: | Size: 41 KiB |
After Width: | Height: | Size: 40 KiB |
After Width: | Height: | Size: 43 KiB |
After Width: | Height: | Size: 37 KiB |
After Width: | Height: | Size: 36 KiB |
After Width: | Height: | Size: 39 KiB |
After Width: | Height: | Size: 44 KiB |
After Width: | Height: | Size: 37 KiB |
After Width: | Height: | Size: 40 KiB |
After Width: | Height: | Size: 41 KiB |
After Width: | Height: | Size: 44 KiB |
After Width: | Height: | Size: 37 KiB |
After Width: | Height: | Size: 38 KiB |
After Width: | Height: | Size: 44 KiB |
After Width: | Height: | Size: 40 KiB |
After Width: | Height: | Size: 37 KiB |
After Width: | Height: | Size: 38 KiB |
After Width: | Height: | Size: 41 KiB |
After Width: | Height: | Size: 43 KiB |
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 39 KiB |
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 39 KiB |
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 36 KiB |
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 37 KiB |
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 35 KiB |
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 39 KiB |
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 35 KiB |
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 35 KiB |
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 38 KiB |
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 40 KiB |
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 39 KiB |
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 37 KiB |
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 39 KiB |
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 35 KiB |
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 37 KiB |
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 38 KiB |
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 40 KiB |
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 35 KiB |
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 37 KiB |
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 44 KiB |
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 40 KiB |
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 40 KiB |
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 49 KiB |
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 43 KiB |
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 42 KiB |
BIN
doc/diagrams/buckets-oa.png
Normal file
After Width: | Height: | Size: 15 KiB |
@ -12,10 +12,10 @@
|
||||
|
||||
include::unordered/intro.adoc[]
|
||||
include::unordered/buckets.adoc[]
|
||||
include::unordered/benchmarks.adoc[]
|
||||
include::unordered/hash_equality.adoc[]
|
||||
include::unordered/comparison.adoc[]
|
||||
include::unordered/compliance.adoc[]
|
||||
include::unordered/benchmarks.adoc[]
|
||||
include::unordered/rationale.adoc[]
|
||||
include::unordered/ref.adoc[]
|
||||
include::unordered/changes.adoc[]
|
||||
|
@ -4,27 +4,29 @@
|
||||
|
||||
= Benchmarks
|
||||
|
||||
All benchmarks were created using `unordered_set<unsigned int>` (non-duplicate) and `unordered_multiset<unsigned int>` (duplicate). The source code can be https://github.com/joaquintides/boost_unordered_benchmark[found here].
|
||||
== boost::unordered_set
|
||||
|
||||
All benchmarks were created using `unordered_set<unsigned int>` (non-duplicate) and `unordered_multiset<unsigned int>` (duplicate). The source code can be https://github.com/joaquintides/boost_unordered_benchmarks/tree/boost_unordered_set[found here^].
|
||||
|
||||
The insertion benchmarks insert `n` random values, where `n` is between 10,000 and 3 million. For the duplicated benchmarks, the same random values are repeated an average of 5 times.
|
||||
|
||||
The erasure benchmarks erase all `n` elements randomly until the container is empty.
|
||||
|
||||
The successful lookup benchmarks are done by looking up all `n` values, in the their original insertion order.
|
||||
The successful lookup benchmarks are done by looking up all `n` values, in their original insertion order.
|
||||
|
||||
The unsuccessful lookup benchmarks use `n` randomly generated integers but using a different seed value.
|
||||
|
||||
== GCC 11 + libstdc++-v3
|
||||
=== GCC 11 + libstdc++-v3, x64
|
||||
|
||||
=== Insertion
|
||||
==== Insertion
|
||||
|
||||
[caption=]
|
||||
[cols="3*^.^a", frame=all, grid=all]
|
||||
|===
|
||||
|
||||
|image::benchmarks/gcc/running insertion.xlsx.practice.png[width=250,link=../diagrams/benchmarks/gcc/running insertion.xlsx.practice.png,window=_blank]
|
||||
|image::benchmarks/gcc/running%20insertion.xlsx.practice non-unique.png[width=250,link=../diagrams/benchmarks/gcc/running%20insertion.xlsx.practice non-unique.png,window=_blank]
|
||||
|image::benchmarks/gcc/running%20insertion.xlsx.practice non-unique 5.png[width=250,link=../diagrams/benchmarks/gcc/running%20insertion.xlsx.practice non-unique 5.png,window=_blank]
|
||||
|image::benchmarks-set/gcc/running insertion.xlsx.practice.png[width=250,link=../diagrams/benchmarks-set/gcc/running insertion.xlsx.practice.png,window=_blank]
|
||||
|image::benchmarks-set/gcc/running%20insertion.xlsx.practice non-unique.png[width=250,link=../diagrams/benchmarks-set/gcc/running%20insertion.xlsx.practice non-unique.png,window=_blank]
|
||||
|image::benchmarks-set/gcc/running%20insertion.xlsx.practice non-unique 5.png[width=250,link=../diagrams/benchmarks-set/gcc/running%20insertion.xlsx.practice non-unique 5.png,window=_blank]
|
||||
|
||||
h|non-duplicate elements
|
||||
h|duplicate elements
|
||||
@ -36,9 +38,9 @@ max load factor 5
|
||||
[cols="3*^.^a", frame=all, grid=all]
|
||||
|===
|
||||
|
||||
|image::benchmarks/gcc/running%20insertion.xlsx.practice norehash.png[width=250,link=../diagrams/benchmarks/gcc/running%20insertion.xlsx.practice norehash.png,window=_blank]
|
||||
|image::benchmarks/gcc/running%20insertion.xlsx.practice norehash non-unique.png[width=250,link=../diagrams/benchmarks/gcc/running%20insertion.xlsx.practice norehash non-unique.png,window=_blank]
|
||||
|image::benchmarks/gcc/running%20insertion.xlsx.practice norehash non-unique 5.png[width=250,link=../diagrams/benchmarks/gcc/running%20insertion.xlsx.practice norehash non-unique 5.png,window=_blank]
|
||||
|image::benchmarks-set/gcc/running%20insertion.xlsx.practice norehash.png[width=250,link=../diagrams/benchmarks-set/gcc/running%20insertion.xlsx.practice norehash.png,window=_blank]
|
||||
|image::benchmarks-set/gcc/running%20insertion.xlsx.practice norehash non-unique.png[width=250,link=../diagrams/benchmarks-set/gcc/running%20insertion.xlsx.practice norehash non-unique.png,window=_blank]
|
||||
|image::benchmarks-set/gcc/running%20insertion.xlsx.practice norehash non-unique 5.png[width=250,link=../diagrams/benchmarks-set/gcc/running%20insertion.xlsx.practice norehash non-unique 5.png,window=_blank]
|
||||
|
||||
h|non-duplicate elements, +
|
||||
prior `reserve`
|
||||
@ -50,15 +52,15 @@ prior `reserve`
|
||||
|
||||
|===
|
||||
|
||||
=== Erasure
|
||||
==== Erasure
|
||||
|
||||
[caption=]
|
||||
[cols="3*^.^a", frame=all, grid=all]
|
||||
|===
|
||||
|
||||
|image::benchmarks/gcc/scattered%20erasure.xlsx.practice.png[width=250,link=../diagrams/benchmarks/gcc/scattered%20erasure.xlsx.practice.png,window=_blank]
|
||||
|image::benchmarks/gcc/scattered%20erasure.xlsx.practice non-unique.png[width=250,link=../diagrams/benchmarks/gcc/scattered%20erasure.xlsx.practice non-unique.png,window=_blank]
|
||||
|image::benchmarks/gcc/scattered%20erasure.xlsx.practice non-unique 5.png[width=250,link=../diagrams/benchmarks/gcc/scattered%20erasure.xlsx.practice non-unique 5.png,window=_blank]
|
||||
|image::benchmarks-set/gcc/scattered%20erasure.xlsx.practice.png[width=250,link=../diagrams/benchmarks-set/gcc/scattered%20erasure.xlsx.practice.png,window=_blank]
|
||||
|image::benchmarks-set/gcc/scattered%20erasure.xlsx.practice non-unique.png[width=250,link=../diagrams/benchmarks-set/gcc/scattered%20erasure.xlsx.practice non-unique.png,window=_blank]
|
||||
|image::benchmarks-set/gcc/scattered%20erasure.xlsx.practice non-unique 5.png[width=250,link=../diagrams/benchmarks-set/gcc/scattered%20erasure.xlsx.practice non-unique 5.png,window=_blank]
|
||||
|
||||
h|non-duplicate elements
|
||||
h|duplicate elements
|
||||
@ -66,15 +68,15 @@ h|duplicate elements +
|
||||
max load factor 5
|
||||
|===
|
||||
|
||||
=== Successful Lookup
|
||||
==== Successful Lookup
|
||||
|
||||
[caption=]
|
||||
[cols="3*^.^a", frame=all, grid=all]
|
||||
|===
|
||||
|
||||
|image::benchmarks/gcc/scattered%20successful%20looukp.xlsx.practice.png[width=250,window=_blank,link=../diagrams/benchmarks/gcc/scattered%20successful%20looukp.xlsx.practice.png]
|
||||
|image::benchmarks/gcc/scattered%20successful%20looukp.xlsx.practice non-unique.png[width=250,window=_blank,link=../diagrams/benchmarks/gcc/scattered%20successful%20looukp.xlsx.practice non-unique.png]
|
||||
|image::benchmarks/gcc/scattered%20successful%20looukp.xlsx.practice non-unique 5.png[width=250,window=_blank,link=../diagrams/benchmarks/gcc/scattered%20successful%20looukp.xlsx.practice non-unique 5.png]
|
||||
|image::benchmarks-set/gcc/scattered%20successful%20looukp.xlsx.practice.png[width=250,window=_blank,link=../diagrams/benchmarks-set/gcc/scattered%20successful%20looukp.xlsx.practice.png]
|
||||
|image::benchmarks-set/gcc/scattered%20successful%20looukp.xlsx.practice non-unique.png[width=250,window=_blank,link=../diagrams/benchmarks-set/gcc/scattered%20successful%20looukp.xlsx.practice non-unique.png]
|
||||
|image::benchmarks-set/gcc/scattered%20successful%20looukp.xlsx.practice non-unique 5.png[width=250,window=_blank,link=../diagrams/benchmarks-set/gcc/scattered%20successful%20looukp.xlsx.practice non-unique 5.png]
|
||||
|
||||
h|non-duplicate elements
|
||||
h|duplicate elements
|
||||
@ -83,15 +85,15 @@ max load factor 5
|
||||
|
||||
|===
|
||||
|
||||
=== Unsuccessful lookup
|
||||
==== Unsuccessful lookup
|
||||
|
||||
[caption=]
|
||||
[cols="3*^.^a", frame=all, grid=all]
|
||||
|===
|
||||
|
||||
|image::benchmarks/gcc/scattered%20unsuccessful%20looukp.xlsx.practice.png[width=250,window=_blank,link=../diagrams/benchmarks/gcc/scattered%20unsuccessful%20looukp.xlsx.practice.png]
|
||||
|image::benchmarks/gcc/scattered%20unsuccessful%20looukp.xlsx.practice non-unique.png[width=250,window=_blank,link=../diagrams/benchmarks/gcc/scattered%20unsuccessful%20looukp.xlsx.practice non-unique.png]
|
||||
|image::benchmarks/gcc/scattered%20unsuccessful%20looukp.xlsx.practice non-unique 5.png[width=250,window=_blank,link=../diagrams/benchmarks/gcc/scattered%20unsuccessful%20looukp.xlsx.practice non-unique 5.png]
|
||||
|image::benchmarks-set/gcc/scattered%20unsuccessful%20looukp.xlsx.practice.png[width=250,window=_blank,link=../diagrams/benchmarks-set/gcc/scattered%20unsuccessful%20looukp.xlsx.practice.png]
|
||||
|image::benchmarks-set/gcc/scattered%20unsuccessful%20looukp.xlsx.practice non-unique.png[width=250,window=_blank,link=../diagrams/benchmarks-set/gcc/scattered%20unsuccessful%20looukp.xlsx.practice non-unique.png]
|
||||
|image::benchmarks-set/gcc/scattered%20unsuccessful%20looukp.xlsx.practice non-unique 5.png[width=250,window=_blank,link=../diagrams/benchmarks-set/gcc/scattered%20unsuccessful%20looukp.xlsx.practice non-unique 5.png]
|
||||
|
||||
h|non-duplicate elements
|
||||
h|duplicate elements
|
||||
@ -100,17 +102,17 @@ max load factor 5
|
||||
|
||||
|===
|
||||
|
||||
== Clang 12 + libc++
|
||||
=== Clang 12 + libc++, x64
|
||||
|
||||
=== Insertion
|
||||
==== Insertion
|
||||
|
||||
[caption=]
|
||||
[cols="3*^.^a", frame=all, grid=all]
|
||||
|===
|
||||
|
||||
|image::benchmarks/clang_libcpp/running%20insertion.xlsx.practice.png[width=250, window=_blank,link=../diagrams/benchmarks/clang_libcpp/running%20insertion.xlsx.practice.png]
|
||||
|image::benchmarks/clang_libcpp/running%20insertion.xlsx.practice non-unique.png[width=250, window=_blank,link=../diagrams/benchmarks/clang_libcpp/running%20insertion.xlsx.practice non-unique.png]
|
||||
|image::benchmarks/clang_libcpp/running%20insertion.xlsx.practice non-unique 5.png[width=250, window=_blank,link=../diagrams/benchmarks/clang_libcpp/running%20insertion.xlsx.practice non-unique 5.png]
|
||||
|image::benchmarks-set/clang_libcpp/running%20insertion.xlsx.practice.png[width=250, window=_blank,link=../diagrams/benchmarks-set/clang_libcpp/running%20insertion.xlsx.practice.png]
|
||||
|image::benchmarks-set/clang_libcpp/running%20insertion.xlsx.practice non-unique.png[width=250, window=_blank,link=../diagrams/benchmarks-set/clang_libcpp/running%20insertion.xlsx.practice non-unique.png]
|
||||
|image::benchmarks-set/clang_libcpp/running%20insertion.xlsx.practice non-unique 5.png[width=250, window=_blank,link=../diagrams/benchmarks-set/clang_libcpp/running%20insertion.xlsx.practice non-unique 5.png]
|
||||
|
||||
h|non-duplicate elements
|
||||
h|duplicate elements
|
||||
@ -123,9 +125,9 @@ max load factor 5
|
||||
[cols="3*^.^a", frame=all, grid=all]
|
||||
|===
|
||||
|
||||
|image::benchmarks/clang_libcpp/running%20insertion.xlsx.practice norehash.png[width=250,window=_blank,link=../diagrams/benchmarks/clang_libcpp/running%20insertion.xlsx.practice norehash.png]
|
||||
|image::benchmarks/clang_libcpp/running%20insertion.xlsx.practice norehash non-unique.png[width=250,window=_blank,link=../diagrams/benchmarks/clang_libcpp/running%20insertion.xlsx.practice norehash non-unique.png]
|
||||
|image::benchmarks/clang_libcpp/running%20insertion.xlsx.practice norehash non-unique 5.png[width=250,window=_blank,link=../diagrams/benchmarks/clang_libcpp/running%20insertion.xlsx.practice norehash non-unique 5.png]
|
||||
|image::benchmarks-set/clang_libcpp/running%20insertion.xlsx.practice norehash.png[width=250,window=_blank,link=../diagrams/benchmarks-set/clang_libcpp/running%20insertion.xlsx.practice norehash.png]
|
||||
|image::benchmarks-set/clang_libcpp/running%20insertion.xlsx.practice norehash non-unique.png[width=250,window=_blank,link=../diagrams/benchmarks-set/clang_libcpp/running%20insertion.xlsx.practice norehash non-unique.png]
|
||||
|image::benchmarks-set/clang_libcpp/running%20insertion.xlsx.practice norehash non-unique 5.png[width=250,window=_blank,link=../diagrams/benchmarks-set/clang_libcpp/running%20insertion.xlsx.practice norehash non-unique 5.png]
|
||||
|
||||
h|non-duplicate elements, +
|
||||
prior `reserve`
|
||||
@ -137,15 +139,15 @@ prior `reserve`
|
||||
|
||||
|===
|
||||
|
||||
=== Erasure
|
||||
==== Erasure
|
||||
|
||||
[caption=]
|
||||
[cols="3*^.^a", frame=all, grid=all]
|
||||
|===
|
||||
|
||||
|image::benchmarks/clang_libcpp/scattered%20erasure.xlsx.practice.png[width=250,window=_blank,link=../diagrams/benchmarks/clang_libcpp/scattered%20erasure.xlsx.practice.png]
|
||||
|image::benchmarks/clang_libcpp/scattered%20erasure.xlsx.practice non-unique.png[width=250,window=_blank,link=../diagrams/benchmarks/clang_libcpp/scattered%20erasure.xlsx.practice non-unique.png]
|
||||
|image::benchmarks/clang_libcpp/scattered%20erasure.xlsx.practice non-unique 5.png[width=250,window=_blank,link=../diagrams/benchmarks/clang_libcpp/scattered%20erasure.xlsx.practice non-unique 5.png]
|
||||
|image::benchmarks-set/clang_libcpp/scattered%20erasure.xlsx.practice.png[width=250,window=_blank,link=../diagrams/benchmarks-set/clang_libcpp/scattered%20erasure.xlsx.practice.png]
|
||||
|image::benchmarks-set/clang_libcpp/scattered%20erasure.xlsx.practice non-unique.png[width=250,window=_blank,link=../diagrams/benchmarks-set/clang_libcpp/scattered%20erasure.xlsx.practice non-unique.png]
|
||||
|image::benchmarks-set/clang_libcpp/scattered%20erasure.xlsx.practice non-unique 5.png[width=250,window=_blank,link=../diagrams/benchmarks-set/clang_libcpp/scattered%20erasure.xlsx.practice non-unique 5.png]
|
||||
|
||||
h|non-duplicate elements
|
||||
h|duplicate elements
|
||||
@ -154,15 +156,15 @@ max load factor 5
|
||||
|
||||
|===
|
||||
|
||||
=== Successful lookup
|
||||
==== Successful lookup
|
||||
|
||||
[caption=]
|
||||
[cols="3*^.^a", frame=all, grid=all]
|
||||
|===
|
||||
|
||||
|image::benchmarks/clang_libcpp/scattered%20successful%20looukp.xlsx.practice.png[width=250,window=_blank,link=../diagrams/benchmarks/clang_libcpp/scattered%20successful%20looukp.xlsx.practice.png]
|
||||
|image::benchmarks/clang_libcpp/scattered%20successful%20looukp.xlsx.practice non-unique.png[width=250,window=_blank,link=../diagrams/benchmarks/clang_libcpp/scattered%20successful%20looukp.xlsx.practice non-unique.png]
|
||||
|image::benchmarks/clang_libcpp/scattered%20successful%20looukp.xlsx.practice non-unique 5.png[width=250,window=_blank,link=../diagrams/benchmarks/clang_libcpp/scattered%20successful%20looukp.xlsx.practice non-unique 5.png]
|
||||
|image::benchmarks-set/clang_libcpp/scattered%20successful%20looukp.xlsx.practice.png[width=250,window=_blank,link=../diagrams/benchmarks-set/clang_libcpp/scattered%20successful%20looukp.xlsx.practice.png]
|
||||
|image::benchmarks-set/clang_libcpp/scattered%20successful%20looukp.xlsx.practice non-unique.png[width=250,window=_blank,link=../diagrams/benchmarks-set/clang_libcpp/scattered%20successful%20looukp.xlsx.practice non-unique.png]
|
||||
|image::benchmarks-set/clang_libcpp/scattered%20successful%20looukp.xlsx.practice non-unique 5.png[width=250,window=_blank,link=../diagrams/benchmarks-set/clang_libcpp/scattered%20successful%20looukp.xlsx.practice non-unique 5.png]
|
||||
|
||||
h|non-duplicate elements
|
||||
h|duplicate elements
|
||||
@ -171,15 +173,15 @@ max load factor 5
|
||||
|
||||
|===
|
||||
|
||||
=== Unsuccessful lookup
|
||||
==== Unsuccessful lookup
|
||||
|
||||
[caption=]
|
||||
[cols="3*^.^a", frame=all, grid=all]
|
||||
|===
|
||||
|
||||
|image::benchmarks/clang_libcpp/scattered%20unsuccessful%20looukp.xlsx.practice.png[width=250,window=_blank,link=../diagrams/benchmarks/clang_libcpp/scattered%20unsuccessful%20looukp.xlsx.practice.png]
|
||||
|image::benchmarks/clang_libcpp/scattered%20unsuccessful%20looukp.xlsx.practice non-unique.png[width=250,window=_blank,link=../diagrams/benchmarks/clang_libcpp/scattered%20unsuccessful%20looukp.xlsx.practice non-unique.png]
|
||||
|image::benchmarks/clang_libcpp/scattered%20unsuccessful%20looukp.xlsx.practice non-unique 5.png[width=250,window=_blank,link=../diagrams/benchmarks/clang_libcpp/scattered%20unsuccessful%20looukp.xlsx.practice non-unique 5.png]
|
||||
|image::benchmarks-set/clang_libcpp/scattered%20unsuccessful%20looukp.xlsx.practice.png[width=250,window=_blank,link=../diagrams/benchmarks-set/clang_libcpp/scattered%20unsuccessful%20looukp.xlsx.practice.png]
|
||||
|image::benchmarks-set/clang_libcpp/scattered%20unsuccessful%20looukp.xlsx.practice non-unique.png[width=250,window=_blank,link=../diagrams/benchmarks-set/clang_libcpp/scattered%20unsuccessful%20looukp.xlsx.practice non-unique.png]
|
||||
|image::benchmarks-set/clang_libcpp/scattered%20unsuccessful%20looukp.xlsx.practice non-unique 5.png[width=250,window=_blank,link=../diagrams/benchmarks-set/clang_libcpp/scattered%20unsuccessful%20looukp.xlsx.practice non-unique 5.png]
|
||||
|
||||
h|non-duplicate elements
|
||||
h|duplicate elements
|
||||
@ -188,17 +190,17 @@ max load factor 5
|
||||
|
||||
|===
|
||||
|
||||
== Visual Studio 2019 + Dinkumware
|
||||
=== Visual Studio 2019 + Dinkumware, x64
|
||||
|
||||
=== Insertion
|
||||
==== Insertion
|
||||
|
||||
[caption=]
|
||||
[cols="3*^.^a", frame=all, grid=all]
|
||||
|===
|
||||
|
||||
|image::benchmarks/vs/running%20insertion.xlsx.practice.png[width=250,window=_blank,link=../diagrams/benchmarks/vs/running%20insertion.xlsx.practice.png]
|
||||
|image::benchmarks/vs/running%20insertion.xlsx.practice non-unique.png[width=250,window=_blank,link=../diagrams/benchmarks/vs/running%20insertion.xlsx.practice non-unique.png]
|
||||
|image::benchmarks/vs/running%20insertion.xlsx.practice non-unique 5.png[width=250,window=_blank,link=../diagrams/benchmarks/vs/running%20insertion.xlsx.practice non-unique 5.png]
|
||||
|image::benchmarks-set/vs/running%20insertion.xlsx.practice.png[width=250,window=_blank,link=../diagrams/benchmarks-set/vs/running%20insertion.xlsx.practice.png]
|
||||
|image::benchmarks-set/vs/running%20insertion.xlsx.practice non-unique.png[width=250,window=_blank,link=../diagrams/benchmarks-set/vs/running%20insertion.xlsx.practice non-unique.png]
|
||||
|image::benchmarks-set/vs/running%20insertion.xlsx.practice non-unique 5.png[width=250,window=_blank,link=../diagrams/benchmarks-set/vs/running%20insertion.xlsx.practice non-unique 5.png]
|
||||
|
||||
h|non-duplicate elements
|
||||
h|duplicate elements
|
||||
@ -211,9 +213,9 @@ max load factor 5
|
||||
[cols="3*^.^a", frame=all, grid=all]
|
||||
|===
|
||||
|
||||
|image::benchmarks/vs/running%20insertion.xlsx.practice norehash.png[width=250,window=_blank,link=../diagrams/benchmarks/vs/running%20insertion.xlsx.practice norehash.png]
|
||||
|image::benchmarks/vs/running%20insertion.xlsx.practice norehash non-unique.png[width=250,window=_blank,link=../diagrams/benchmarks/vs/running%20insertion.xlsx.practice norehash non-unique.png]
|
||||
|image::benchmarks/vs/running%20insertion.xlsx.practice norehash non-unique 5.png[width=250,window=_blank,link=../diagrams/benchmarks/vs/running%20insertion.xlsx.practice norehash non-unique 5.png]
|
||||
|image::benchmarks-set/vs/running%20insertion.xlsx.practice norehash.png[width=250,window=_blank,link=../diagrams/benchmarks-set/vs/running%20insertion.xlsx.practice norehash.png]
|
||||
|image::benchmarks-set/vs/running%20insertion.xlsx.practice norehash non-unique.png[width=250,window=_blank,link=../diagrams/benchmarks-set/vs/running%20insertion.xlsx.practice norehash non-unique.png]
|
||||
|image::benchmarks-set/vs/running%20insertion.xlsx.practice norehash non-unique 5.png[width=250,window=_blank,link=../diagrams/benchmarks-set/vs/running%20insertion.xlsx.practice norehash non-unique 5.png]
|
||||
|
||||
h|non-duplicate elements, +
|
||||
prior `reserve`
|
||||
@ -225,15 +227,15 @@ prior `reserve`
|
||||
|
||||
|===
|
||||
|
||||
=== Erasure
|
||||
==== Erasure
|
||||
|
||||
[caption=]
|
||||
[cols="3*^.^a", frame=all, grid=all]
|
||||
|===
|
||||
|
||||
|image::benchmarks/vs/scattered%20erasure.xlsx.practice.png[width=250,window=_blank,link=../diagrams/benchmarks/vs/scattered%20erasure.xlsx.practice.png]
|
||||
|image::benchmarks/vs/scattered%20erasure.xlsx.practice non-unique.png[width=250,window=_blank,link=../diagrams/benchmarks/vs/scattered%20erasure.xlsx.practice non-unique.png]
|
||||
|image::benchmarks/vs/scattered%20erasure.xlsx.practice non-unique 5.png[width=250,window=_blank,link=../diagrams/benchmarks/vs/scattered%20erasure.xlsx.practice non-unique 5.png]
|
||||
|image::benchmarks-set/vs/scattered%20erasure.xlsx.practice.png[width=250,window=_blank,link=../diagrams/benchmarks-set/vs/scattered%20erasure.xlsx.practice.png]
|
||||
|image::benchmarks-set/vs/scattered%20erasure.xlsx.practice non-unique.png[width=250,window=_blank,link=../diagrams/benchmarks-set/vs/scattered%20erasure.xlsx.practice non-unique.png]
|
||||
|image::benchmarks-set/vs/scattered%20erasure.xlsx.practice non-unique 5.png[width=250,window=_blank,link=../diagrams/benchmarks-set/vs/scattered%20erasure.xlsx.practice non-unique 5.png]
|
||||
|
||||
h|non-duplicate elements
|
||||
h|duplicate elements
|
||||
@ -242,15 +244,15 @@ max load factor 5
|
||||
|
||||
|===
|
||||
|
||||
=== Successful lookup
|
||||
==== Successful lookup
|
||||
|
||||
[caption=]
|
||||
[cols="3*^.^a", frame=all, grid=all]
|
||||
|===
|
||||
|
||||
|image::benchmarks/vs/scattered%20successful%20looukp.xlsx.practice.png[width=250,window=_blank,link=../diagrams/benchmarks/vs/scattered%20successful%20looukp.xlsx.practice.png]
|
||||
|image::benchmarks/vs/scattered%20successful%20looukp.xlsx.practice non-unique.png[width=250,window=_blank,link=../diagrams/benchmarks/vs/scattered%20successful%20looukp.xlsx.practice non-unique.png]
|
||||
|image::benchmarks/vs/scattered%20successful%20looukp.xlsx.practice non-unique 5.png[width=250,window=_blank,link=../diagrams/benchmarks/vs/scattered%20successful%20looukp.xlsx.practice non-unique 5.png]
|
||||
|image::benchmarks-set/vs/scattered%20successful%20looukp.xlsx.practice.png[width=250,window=_blank,link=../diagrams/benchmarks-set/vs/scattered%20successful%20looukp.xlsx.practice.png]
|
||||
|image::benchmarks-set/vs/scattered%20successful%20looukp.xlsx.practice non-unique.png[width=250,window=_blank,link=../diagrams/benchmarks-set/vs/scattered%20successful%20looukp.xlsx.practice non-unique.png]
|
||||
|image::benchmarks-set/vs/scattered%20successful%20looukp.xlsx.practice non-unique 5.png[width=250,window=_blank,link=../diagrams/benchmarks-set/vs/scattered%20successful%20looukp.xlsx.practice non-unique 5.png]
|
||||
|
||||
h|non-duplicate elements
|
||||
h|duplicate elements
|
||||
@ -259,15 +261,15 @@ max load factor 5
|
||||
|
||||
|===
|
||||
|
||||
=== Unsuccessful lookup
|
||||
==== Unsuccessful lookup
|
||||
|
||||
[caption=]
|
||||
[cols="3*^.^a", frame=all, grid=all]
|
||||
|===
|
||||
|
||||
|image::benchmarks/vs/scattered%20unsuccessful%20looukp.xlsx.practice.png[width=250,window=_blank,link=../diagrams/benchmarks/vs/scattered%20unsuccessful%20looukp.xlsx.practice.png]
|
||||
|image::benchmarks/vs/scattered%20unsuccessful%20looukp.xlsx.practice non-unique.png[width=250,window=_blank,link=../diagrams/benchmarks/vs/scattered%20unsuccessful%20looukp.xlsx.practice non-unique.png]
|
||||
|image::benchmarks/vs/scattered%20unsuccessful%20looukp.xlsx.practice non-unique 5.png[width=250,window=_blank,link=../diagrams/benchmarks/vs/scattered%20unsuccessful%20looukp.xlsx.practice non-unique 5.png]
|
||||
|image::benchmarks-set/vs/scattered%20unsuccessful%20looukp.xlsx.practice.png[width=250,window=_blank,link=../diagrams/benchmarks-set/vs/scattered%20unsuccessful%20looukp.xlsx.practice.png]
|
||||
|image::benchmarks-set/vs/scattered%20unsuccessful%20looukp.xlsx.practice non-unique.png[width=250,window=_blank,link=../diagrams/benchmarks-set/vs/scattered%20unsuccessful%20looukp.xlsx.practice non-unique.png]
|
||||
|image::benchmarks-set/vs/scattered%20unsuccessful%20looukp.xlsx.practice non-unique 5.png[width=250,window=_blank,link=../diagrams/benchmarks-set/vs/scattered%20unsuccessful%20looukp.xlsx.practice non-unique 5.png]
|
||||
|
||||
h|non-duplicate elements
|
||||
h|duplicate elements
|
||||
@ -275,3 +277,156 @@ h|duplicate elements, +
|
||||
max load factor 5
|
||||
|
||||
|===
|
||||
|
||||
== boost::unordered_flat_map
|
||||
|
||||
All benchmarks were created using:
|
||||
|
||||
* `https://abseil.io/docs/cpp/guides/container[absl::flat_hash_map^]<uint64_t, uint64_t>`
|
||||
* `boost::unordered_flat_map<uint64_t, uint64_t>`
|
||||
* `boost::unordered_map<uint64_t, uint64_t>`
|
||||
|
||||
The source code can be https://github.com/joaquintides/boost_unordered_benchmarks/tree/boost_unordered_flat_map[found here^].
|
||||
|
||||
The insertion benchmarks insert `n` random values, where `n` is between 10,000 and 10 million.
|
||||
|
||||
The erasure benchmarks erase traverse the `n` elements and erase those with odd key (50% on average).
|
||||
|
||||
The successful lookup benchmarks are done by looking up all `n` values, in their original insertion order.
|
||||
|
||||
The unsuccessful lookup benchmarks use `n` randomly generated integers but using a different seed value.
|
||||
|
||||
|
||||
=== GCC 11, x64
|
||||
|
||||
|
||||
[caption=]
|
||||
[cols="4*^.^a", frame=all, grid=all]
|
||||
|===
|
||||
|
||||
|image::benchmarks-flat_map/gcc-x64/Running%20insertion.xlsx.plot.png[width=250,window=_blank,link=../diagrams/benchmarks-flat_map/gcc-x64/Running%20insertion.xlsx.plot.png]
|
||||
|image::benchmarks-flat_map/gcc-x64/Running%20erasure.xlsx.plot.png[width=250,window=_blank,link=../diagrams/benchmarks-flat_map/gcc-x64/Running%20erasure.xlsx.plot.png]
|
||||
|image::benchmarks-flat_map/gcc-x64/Scattered%20successful%20looukp.xlsx.plot.png[width=250,window=_blank,link=../diagrams/benchmarks-flat_map/gcc-x64/Scattered%20successful%20looukp.xlsx.plot.png]
|
||||
|image::benchmarks-flat_map/gcc-x64/Scattered%20unsuccessful%20looukp.xlsx.plot.png[width=250,window=_blank,link=../diagrams/benchmarks-flat_map/gcc-x64/Scattered%20unsuccessful%20looukp.xlsx.plot.png]
|
||||
|
||||
h|running insertion
|
||||
h|running erasure
|
||||
h|successful lookup
|
||||
h|unsuccessful lookup
|
||||
|
||||
|===
|
||||
|
||||
=== Clang 12, x64
|
||||
|
||||
|
||||
[caption=]
|
||||
[cols="4*^.^a", frame=all, grid=all]
|
||||
|===
|
||||
|
||||
|image::benchmarks-flat_map/clang-x64/Running%20insertion.xlsx.plot.png[width=250,window=_blank,link=../diagrams/benchmarks-flat_map/clang-x64/Running%20insertion.xlsx.plot.png]
|
||||
|image::benchmarks-flat_map/clang-x64/Running%20erasure.xlsx.plot.png[width=250,window=_blank,link=../diagrams/benchmarks-flat_map/clang-x64/Running%20erasure.xlsx.plot.png]
|
||||
|image::benchmarks-flat_map/clang-x64/Scattered%20successful%20looukp.xlsx.plot.png[width=250,window=_blank,link=../diagrams/benchmarks-flat_map/clang-x64/Scattered%20successful%20looukp.xlsx.plot.png]
|
||||
|image::benchmarks-flat_map/clang-x64/Scattered%20unsuccessful%20looukp.xlsx.plot.png[width=250,window=_blank,link=../diagrams/benchmarks-flat_map/clang-x64/Scattered%20unsuccessful%20looukp.xlsx.plot.png]
|
||||
|
||||
h|running insertion
|
||||
h|running erasure
|
||||
h|successful lookup
|
||||
h|unsuccessful lookup
|
||||
|
||||
|===
|
||||
|
||||
=== Visual Studio 2019, x64
|
||||
|
||||
|
||||
[caption=]
|
||||
[cols="4*^.^a", frame=all, grid=all]
|
||||
|===
|
||||
|
||||
|image::benchmarks-flat_map/vs-x64/Running%20insertion.xlsx.plot.png[width=250,window=_blank,link=../diagrams/benchmarks-flat_map/vs-x64/Running%20insertion.xlsx.plot.png]
|
||||
|image::benchmarks-flat_map/vs-x64/Running%20erasure.xlsx.plot.png[width=250,window=_blank,link=../diagrams/benchmarks-flat_map/vs-x64/Running%20erasure.xlsx.plot.png]
|
||||
|image::benchmarks-flat_map/vs-x64/Scattered%20successful%20looukp.xlsx.plot.png[width=250,window=_blank,link=../diagrams/benchmarks-flat_map/vs-x64/Scattered%20successful%20looukp.xlsx.plot.png]
|
||||
|image::benchmarks-flat_map/vs-x64/Scattered%20unsuccessful%20looukp.xlsx.plot.png[width=250,window=_blank,link=../diagrams/benchmarks-flat_map/vs-x64/Scattered%20unsuccessful%20looukp.xlsx.plot.png]
|
||||
|
||||
h|running insertion
|
||||
h|running erasure
|
||||
h|successful lookup
|
||||
h|unsuccessful lookup
|
||||
|
||||
|===
|
||||
|
||||
=== Clang 12, ARM64
|
||||
|
||||
|
||||
[caption=]
|
||||
[cols="4*^.^a", frame=all, grid=all]
|
||||
|===
|
||||
|
||||
|image::benchmarks-flat_map/clang-arm64/Running%20insertion.xlsx.plot.png[width=250,window=_blank,link=../diagrams/benchmarks-flat_map/clang-arm64/Running%20insertion.xlsx.plot.png]
|
||||
|image::benchmarks-flat_map/clang-arm64/Running%20erasure.xlsx.plot.png[width=250,window=_blank,link=../diagrams/benchmarks-flat_map/clang-arm64/Running%20erasure.xlsx.plot.png]
|
||||
|image::benchmarks-flat_map/clang-arm64/Scattered%20successful%20looukp.xlsx.plot.png[width=250,window=_blank,link=../diagrams/benchmarks-flat_map/clang-arm64/Scattered%20successful%20looukp.xlsx.plot.png]
|
||||
|image::benchmarks-flat_map/clang-arm64/Scattered%20unsuccessful%20looukp.xlsx.plot.png[width=250,window=_blank,link=../diagrams/benchmarks-flat_map/clang-arm64/Scattered%20unsuccessful%20looukp.xlsx.plot.png]
|
||||
|
||||
h|running insertion
|
||||
h|running erasure
|
||||
h|successful lookup
|
||||
h|unsuccessful lookup
|
||||
|
||||
|===
|
||||
|
||||
=== GCC 11, x86
|
||||
|
||||
|
||||
[caption=]
|
||||
[cols="4*^.^a", frame=all, grid=all]
|
||||
|===
|
||||
|
||||
|image::benchmarks-flat_map/gcc-x86/Running%20insertion.xlsx.plot.png[width=250,window=_blank,link=../diagrams/benchmarks-flat_map/gcc-x86/Running%20insertion.xlsx.plot.png]
|
||||
|image::benchmarks-flat_map/gcc-x86/Running%20erasure.xlsx.plot.png[width=250,window=_blank,link=../diagrams/benchmarks-flat_map/gcc-x86/Running%20erasure.xlsx.plot.png]
|
||||
|image::benchmarks-flat_map/gcc-x86/Scattered%20successful%20looukp.xlsx.plot.png[width=250,window=_blank,link=../diagrams/benchmarks-flat_map/gcc-x86/Scattered%20successful%20looukp.xlsx.plot.png]
|
||||
|image::benchmarks-flat_map/gcc-x86/Scattered%20unsuccessful%20looukp.xlsx.plot.png[width=250,window=_blank,link=../diagrams/benchmarks-flat_map/gcc-x86/Scattered%20unsuccessful%20looukp.xlsx.plot.png]
|
||||
|
||||
h|running insertion
|
||||
h|running erasure
|
||||
h|successful lookup
|
||||
h|unsuccessful lookup
|
||||
|
||||
|===
|
||||
|
||||
=== Clang 12, x64
|
||||
|
||||
|
||||
[caption=]
|
||||
[cols="4*^.^a", frame=all, grid=all]
|
||||
|===
|
||||
|
||||
|image::benchmarks-flat_map/clang-x86/Running%20insertion.xlsx.plot.png[width=250,window=_blank,link=../diagrams/benchmarks-flat_map/clang-x86/Running%20insertion.xlsx.plot.png]
|
||||
|image::benchmarks-flat_map/clang-x86/Running%20erasure.xlsx.plot.png[width=250,window=_blank,link=../diagrams/benchmarks-flat_map/clang-x86/Running%20erasure.xlsx.plot.png]
|
||||
|image::benchmarks-flat_map/clang-x86/Scattered%20successful%20looukp.xlsx.plot.png[width=250,window=_blank,link=../diagrams/benchmarks-flat_map/clang-x86/Scattered%20successful%20looukp.xlsx.plot.png]
|
||||
|image::benchmarks-flat_map/clang-x86/Scattered%20unsuccessful%20looukp.xlsx.plot.png[width=250,window=_blank,link=../diagrams/benchmarks-flat_map/clang-x86/Scattered%20unsuccessful%20looukp.xlsx.plot.png]
|
||||
|
||||
h|running insertion
|
||||
h|running erasure
|
||||
h|successful lookup
|
||||
h|unsuccessful lookup
|
||||
|
||||
|===
|
||||
|
||||
=== Visual Studio 2019, x86
|
||||
|
||||
|
||||
[caption=]
|
||||
[cols="4*^.^a", frame=all, grid=all]
|
||||
|===
|
||||
|
||||
|image::benchmarks-flat_map/vs-x86/Running%20insertion.xlsx.plot.png[width=250,window=_blank,link=../diagrams/benchmarks-flat_map/vs-x86/Running%20insertion.xlsx.plot.png]
|
||||
|image::benchmarks-flat_map/vs-x86/Running%20erasure.xlsx.plot.png[width=250,window=_blank,link=../diagrams/benchmarks-flat_map/vs-x86/Running%20erasure.xlsx.plot.png]
|
||||
|image::benchmarks-flat_map/vs-x86/Scattered%20successful%20looukp.xlsx.plot.png[width=250,window=_blank,link=../diagrams/benchmarks-flat_map/vs-x86/Scattered%20successful%20looukp.xlsx.plot.png]
|
||||
|image::benchmarks-flat_map/vs-x86/Scattered%20unsuccessful%20looukp.xlsx.plot.png[width=250,window=_blank,link=../diagrams/benchmarks-flat_map/vs-x86/Scattered%20unsuccessful%20looukp.xlsx.plot.png]
|
||||
|
||||
h|running insertion
|
||||
h|running erasure
|
||||
h|successful lookup
|
||||
h|unsuccessful lookup
|
||||
|
||||
|===
|
||||
|
||||
|
@ -5,6 +5,8 @@
|
||||
= Bibliography
|
||||
|
||||
* _C/C++ Users Journal_. February, 2006. Pete Becker. http://www.ddj.com/cpp/184402066[STL and TR1: Part III - Unordered containers^]. +
|
||||
An introducation to the standard unordered containers.
|
||||
|
||||
An introduction to the standard unordered containers.
|
||||
* _Wikipedia_. https://en.wikipedia.org/wiki/Hash_table[Hash table^]. +
|
||||
An introduction to hash table implementations. Discusses the differences between closed-addressing and open-addressing approaches.
|
||||
* Peter Dimov, 2022. https://pdimov.github.io/articles/unordered_dev_plan.html[Development Plan for Boost.Unordered^].
|
||||
|
||||
|
@ -37,7 +37,7 @@ keep collisions to a minimum.
|
||||
If instead of `boost::unordered_set` we had used <<unordered_flat_set,`boost::unordered_flat_set`>>, the
|
||||
diagram would look as follows:
|
||||
|
||||
image::buckets oa.png[]
|
||||
image::buckets-oa.png[]
|
||||
|
||||
In open-addressing containers, buckets can hold at most one element; if a collision happens
|
||||
(like is the case of `D` in the example), the element uses some other available bucket in
|
||||
@ -144,9 +144,9 @@ h|*Method* h|*Description*
|
||||
|
||||
A note on `max_load` for open-addressing containers: the maximum load will naturally decrease when
|
||||
new insertions are performed, but _won't_ increase at the same rate when erasing: for instance,
|
||||
adding 1,000 elements to a <<unordered_flat_map,`boost::unordered_flat_map`>> and then
|
||||
erasing those 1,000 elements will typically reduce the maximum load by around 160 rather
|
||||
than restoring it to its original value. This is done internally by Boost.Unordered in order
|
||||
adding 1,000 elements to a <<unordered_flat_map,`boost::unordered_flat_map`>> under high load
|
||||
conditions and then erasing 1,000 elements will typically reduce the maximum load by around
|
||||
a few dozen elements rather than restoring it to its original value. This is done internally by Boost.Unordered in order
|
||||
to keep its performance stable, and must be taken into account when planning for rehash-free insertions.
|
||||
The maximum load will be reset to its theoretical maximum
|
||||
(`max_load_factor() * bucket_count()`) right after `rehash`.
|
||||
|
@ -7,9 +7,9 @@
|
||||
|
||||
== Closed-addressing containers: unordered_[multi]set, unordered_[multi]map
|
||||
|
||||
The intent of Boost.Unordered is to implement a close (but imperfect)
|
||||
implementation of the {cpp}17 standard, that will work with {cpp}98 upwards.
|
||||
The wide compatibility does mean some comprimises have to be made.
|
||||
The intent of Boost.Unordered is to provide a conformant
|
||||
implementation of the {cpp}20 standard that will work with {cpp}98 upwards.
|
||||
This wide compatibility does mean some compromises have to be made.
|
||||
With a compiler and library that fully support {cpp}11, the differences should
|
||||
be minor.
|
||||
|
||||
@ -139,5 +139,5 @@ The main differences with C++ unordered associative containers are:
|
||||
* `erase(iterator)` returns `void` instead of an iterator to the following element.
|
||||
* There is no API for bucket handling (except `bucket_count`) or node extraction/insertion.
|
||||
* The maximum load factor of the container is managed internally and can't be set by the user. The maximum load,
|
||||
exposed through the public function `max_load`, can not increase monotonically with the number of erasures.
|
||||
exposed through the public function `max_load`, does not increase monotonically with the number of erasures.
|
||||
|
||||
|
@ -17,7 +17,7 @@ has a good summary of the implementation issues for hash tables in general.
|
||||
=== Data Structure
|
||||
|
||||
By specifying an interface for accessing the buckets of the container the
|
||||
standard pretty much requires that the hash table uses chained addressing.
|
||||
standard pretty much requires that the hash table uses closed addressing.
|
||||
|
||||
It would be conceivable to write a hash table that uses another method. For
|
||||
example, it could use open addressing, and use the lookup chain to act as a
|
||||
@ -34,10 +34,10 @@ bucket but there are some serious problems with this:
|
||||
restrictions could prevent a rehash when it's really needed. The maximum load
|
||||
factor could be set to a fairly low value to work around this - but the
|
||||
standard requires that it is initially set to 1.0.
|
||||
* And since the standard is written with a eye towards chained
|
||||
* And since the standard is written with a eye towards closed
|
||||
addressing, users will be surprised if the performance doesn't reflect that.
|
||||
|
||||
So chained addressing is used.
|
||||
So closed addressing is used.
|
||||
|
||||
=== Number of Buckets
|
||||
|
||||
@ -89,8 +89,8 @@ We discuss here the most relevant principles.
|
||||
|
||||
Given its rich functionality and cross-platform interoperability,
|
||||
`boost::hash` remains the default hash function of `boost::unordered_flat_set` and `boost::unordered_flat_map`.
|
||||
As it happens, `boost::hash` for integral and other basic types does not provide
|
||||
the good statistical properties required by open addressing; to cope with this,
|
||||
As it happens, `boost::hash` for integral and other basic types does not possess
|
||||
the statistical properties required by open addressing; to cope with this,
|
||||
we implement a post-mixing stage:
|
||||
|
||||
* 64-bit architectures: we use the `xmx` function defined in
|
||||
@ -112,4 +112,4 @@ operations.
|
||||
Although the implementation internally uses SIMD technologies, such as https://en.wikipedia.org/wiki/SSE2[SSE2^]
|
||||
and https://en.wikipedia.org/wiki/ARM_architecture_family#Advanced_SIMD_(NEON)[Neon^], when available,
|
||||
this does not affect interoperatility. For instance, the behavior is the same
|
||||
for Visual Studio on an Intel CPU with SSE2 in x64 and for GCC on an IBM s390x without any supported SIMD technology.
|
||||
for Visual Studio on an x64-mode Intel CPU with SSE2 and for GCC on an IBM s390x without any supported SIMD technology.
|
||||
|
@ -7,3 +7,4 @@ include::unordered_set.adoc[]
|
||||
include::unordered_multiset.adoc[]
|
||||
include::hash_traits.adoc[]
|
||||
include::unordered_flat_map.adoc[]
|
||||
include::unordered_flat_set.adoc[]
|
||||
|
@ -145,12 +145,6 @@ namespace boost {
|
||||
template<class M>
|
||||
iterator xref:#unordered_flat_map_insert_or_assign_with_hint[insert_or_assign](const_iterator hint, key_type&& k, M&& obj);
|
||||
|
||||
node_type xref:#unordered_flat_map_extract_by_iterator[extract](const_iterator position);
|
||||
node_type xref:#unordered_flat_map_extract_by_key[extract](const key_type& k);
|
||||
template<class K> node_type xref:#unordered_flat_map_transparent_extract_by_key[extract](K&& k);
|
||||
insert_return_type xref:#unordered_flat_map_insert_with_node_handle[insert](node_type&& nh);
|
||||
iterator xref:#unordered_flat_map_insert_with_hint_and_node_handle[insert](const_iterator hint, node_type&& nh);
|
||||
|
||||
void xref:#unordered_flat_map_erase_by_position[erase](iterator position);
|
||||
void xref:#unordered_flat_map_erase_by_position[erase](const_iterator position);
|
||||
size_type xref:#unordered_flat_map_erase_by_key[erase](const key_type& k);
|
||||
@ -204,6 +198,7 @@ namespace boost {
|
||||
float xref:#unordered_flat_map_load_factor[load_factor]() const noexcept;
|
||||
float xref:#unordered_flat_map_max_load_factor[max_load_factor]() const noexcept;
|
||||
void xref:#unordered_flat_map_set_max_load_factor[max_load_factor](float z);
|
||||
size_type xref:#unordered_flat_map_max_load[max_load]() const noexcept;
|
||||
void xref:#unordered_flat_map_rehash[rehash](size_type n);
|
||||
void xref:#unordered_flat_map_reserve[reserve](size_type n);
|
||||
};
|
||||
@ -250,7 +245,7 @@ https://en.cppreference.com/w/cpp/named_req/Erasable[Erasable^] from the contain
|
||||
|A unary function object type that acts a hash function for a `Key`. It takes a single argument of type `Key` and returns a value of type `std::size_t`.
|
||||
|
||||
|_Pred_
|
||||
|A binary function object that implements an equivalence relation on values of type `Key`. A binary function object that induces an equivalence relation on values of type `Key`. It takes two arguments of type `Key` and returns a value of type `bool`.
|
||||
|A binary function object that induces an equivalence relation on values of type `Key`. It takes two arguments of type `Key` and returns a value of type `bool`.
|
||||
|
||||
|_Allocator_
|
||||
|An allocator whose value type is the same as the container's value type.
|
||||
@ -266,7 +261,7 @@ original position is used.
|
||||
The size of the bucket array can be automatically increased by a call to `insert`/`emplace`, or as a result of calling
|
||||
`rehash`/`reserve`. The _load factor_ of the container (number of elements divided by number of buckets) is never
|
||||
greater than `max_load_factor()`, except possibly for small sizes where the implementation may decide to
|
||||
allow for higher load factors.
|
||||
allow for higher loads.
|
||||
|
||||
If `xref:hash_traits_hash_is_avalanching[hash_is_avalanching]<Hash>::value` is `true`, the hash function
|
||||
is used as-is; otherwise, a bit-mixing post-processing stage is added to increase the quality of hashing
|
||||
@ -317,9 +312,9 @@ Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type`
|
||||
==== Bucket Count Constructor
|
||||
```c++
|
||||
explicit unordered_flat_map(size_type n,
|
||||
const hasher& hf = hasher(),
|
||||
const key_equal& eql = key_equal(),
|
||||
const allocator_type& a = allocator_type());
|
||||
const hasher& hf = hasher(),
|
||||
const key_equal& eql = key_equal(),
|
||||
const allocator_type& a = allocator_type());
|
||||
```
|
||||
|
||||
Constructs an empty container with at least `n` buckets, using `hf` as the hash
|
||||
@ -563,7 +558,7 @@ const_iterator begin() const noexcept;
|
||||
|
||||
[horizontal]
|
||||
Returns:;; An iterator referring to the first element of the container, or if the container is empty the past-the-end value for the container.
|
||||
Complexity:;; Linear
|
||||
Complexity:;; O(`bucket_count()`)
|
||||
|
||||
---
|
||||
|
||||
@ -585,7 +580,7 @@ const_iterator cbegin() const noexcept;
|
||||
|
||||
[horizontal]
|
||||
Returns:;; A `const_iterator` referring to the first element of the container, or if the container is empty the past-the-end value for the container.
|
||||
Complexity:;; Linear
|
||||
Complexity:;; O(`bucket_count()`)
|
||||
|
||||
---
|
||||
|
||||
@ -649,7 +644,7 @@ Returns:;; The `bool` component of the return type is `true` if an insert took p
|
||||
+
|
||||
If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key.
|
||||
Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect.
|
||||
Notes:;; Can invalidate iterators, pointers and references, but only if the insert causes the load factor to be greater than the maximum load factor. +
|
||||
Notes:;; Can invalidate iterators, pointers and references, but only if the insert causes the load to be greater than the maximum load. +
|
||||
|
||||
---
|
||||
|
||||
@ -668,7 +663,7 @@ Returns:;; The `bool` component of the return type is `true` if an insert took p
|
||||
+
|
||||
If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key.
|
||||
Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect.
|
||||
Notes:;; Can invalidate iterators, pointers and references, but only if the insert causes the load factor to be greater than the maximum load factor. +
|
||||
Notes:;; Can invalidate iterators, pointers and references, but only if the insert causes the load to be greater than the maximum load. +
|
||||
|
||||
---
|
||||
|
||||
@ -686,7 +681,7 @@ Returns:;; The `bool` component of the return type is `true` if an insert took p
|
||||
+
|
||||
If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key.
|
||||
Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect.
|
||||
Notes:;; Can invalidate iterators, pointers and references, but only if the insert causes the load factor to be greater than the maximum load factor. +
|
||||
Notes:;; Can invalidate iterators, pointers and references, but only if the insert causes the load to be greater than the maximum load. +
|
||||
+
|
||||
A call of the form `insert(x)`, where `x` is equally convertible to both `const value_type&` and `const init_type&`, is not ambiguous and selects the `init_type` overload.
|
||||
|
||||
@ -706,7 +701,7 @@ Returns:;; The `bool` component of the return type is `true` if an insert took p
|
||||
+
|
||||
If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key.
|
||||
Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect.
|
||||
Notes:;; Can invalidate iterators, pointers and references, but only if the insert causes the load factor to be greater than the maximum load factor. +
|
||||
Notes:;; Can invalidate iterators, pointers and references, but only if the insert causes the load to be greater than the maximum load. +
|
||||
+
|
||||
A call of the form `insert(x)`, where `x` is equally convertible to both `value_type&&` and `init_type&&`, is not ambiguous and selects the `init_type` overload.
|
||||
|
||||
@ -727,7 +722,7 @@ Returns:;; The `bool` component of the return type is `true` if an insert took p
|
||||
+
|
||||
If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key.
|
||||
Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect.
|
||||
Notes:;; Can invalidate iterators, pointers and references, but only if the insert causes the load factor to be greater than the maximum load factor. +
|
||||
Notes:;; Can invalidate iterators, pointers and references, but only if the insert causes the load to be greater than the maximum load. +
|
||||
+
|
||||
A call of the form `insert(hint, x)`, where `x` is equally convertible to both `const value_type&` and `const init_type&`, is not ambiguous and selects the `init_type` overload.
|
||||
|
||||
@ -749,7 +744,7 @@ Returns:;; The `bool` component of the return type is `true` if an insert took p
|
||||
+
|
||||
If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key.
|
||||
Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect.
|
||||
Notes:;; Can invalidate iterators, pointers and references, but only if the insert causes the load factor to be greater than the maximum load factor. +
|
||||
Notes:;; Can invalidate iterators, pointers and references, but only if the insert causes the load to be greater than the maximum load. +
|
||||
+
|
||||
A call of the form `insert(hint, x)`, where `x` is equally convertible to both `value_type&&` and `init_type&&`, is not ambiguous and selects the `init_type` overload.
|
||||
|
||||
@ -765,7 +760,7 @@ Inserts a range of elements into the container. Elements are inserted if and onl
|
||||
[horizontal]
|
||||
Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] into the container from `*first`.
|
||||
Throws:;; When inserting a single element, if an exception is thrown by an operation other than a call to `hasher` the function has no effect.
|
||||
Notes:;; Can invalidate iterators, pointers and references, but only if the insert causes the load factor to be greater than the maximum load factor.
|
||||
Notes:;; Can invalidate iterators, pointers and references, but only if the insert causes the load to be greater than the maximum load.
|
||||
|
||||
---
|
||||
|
||||
@ -779,7 +774,7 @@ Inserts a range of elements into the container. Elements are inserted if and onl
|
||||
[horizontal]
|
||||
Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] into the container from `*first`.
|
||||
Throws:;; When inserting a single element, if an exception is thrown by an operation other than a call to `hasher` the function has no effect.
|
||||
Notes:;; Can invalidate iterators, pointers and references, but only if the insert causes the load factor to be greater than the maximum load factor.
|
||||
Notes:;; Can invalidate iterators, pointers and references, but only if the insert causes the load to be greater than the maximum load.
|
||||
|
||||
---
|
||||
|
||||
@ -812,7 +807,7 @@ value_type(std::piecewise_construct,
|
||||
|
||||
unlike xref:#unordered_flat_map_emplace[emplace], which simply forwards all arguments to ``value_type``'s constructor.
|
||||
|
||||
Can invalidate iterators pointers and references, but only if the insert causes the load factor to be greater than the maximum load factor.
|
||||
Can invalidate iterators pointers and references, but only if the insert causes the load to be greater than the maximum load.
|
||||
|
||||
--
|
||||
|
||||
@ -847,7 +842,7 @@ value_type(std::piecewise_construct,
|
||||
|
||||
unlike xref:#unordered_flat_map_emplace_hint[emplace_hint], which simply forwards all arguments to ``value_type``'s constructor.
|
||||
|
||||
Can invalidate iterators pointers and references, but only if the insert causes the load factor to be greater than the maximum load factor.
|
||||
Can invalidate iterators pointers and references, but only if the insert causes the load to be greater than the maximum load.
|
||||
|
||||
--
|
||||
|
||||
@ -877,7 +872,7 @@ Returns:;; The `bool` component of the return type is `true` if an insert took p
|
||||
+
|
||||
If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key.
|
||||
Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect.
|
||||
Notes:;; Can invalidate iterators pointers and references, but only if the insert causes the load factor to be greater than the maximum load factor. +
|
||||
Notes:;; Can invalidate iterators pointers and references, but only if the insert causes the load to be greater than the maximum load. +
|
||||
|
||||
---
|
||||
|
||||
@ -905,7 +900,7 @@ value_type(std::piecewise_construct,
|
||||
[horizontal]
|
||||
Returns:;; If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key.
|
||||
Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect.
|
||||
Notes:;; Can invalidate iterators, pointers and references, but only if the insert causes the load factor to be greater than the maximum load factor.
|
||||
Notes:;; Can invalidate iterators, pointers and references, but only if the insert causes the load to be greater than the maximum load.
|
||||
|
||||
---
|
||||
|
||||
@ -991,7 +986,7 @@ void clear() noexcept;
|
||||
Erases all elements in the container.
|
||||
|
||||
[horizontal]
|
||||
Postconditions:;; `size() == 0`
|
||||
Postconditions:;; `size() == 0`, `max_load() >= max_load_factor() * bucket_count()`
|
||||
|
||||
---
|
||||
|
||||
@ -1108,7 +1103,7 @@ mapped_type& operator[](key_type&& k);
|
||||
Effects:;; If the container does not already contain an element with a key equivalent to `k`, inserts the value `std::pair<key_type const, mapped_type>(k, mapped_type())`.
|
||||
Returns:;; A reference to `x.second` where `x` is the element already in the container, or the newly inserted element with a key equivalent to `k`.
|
||||
Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect.
|
||||
Notes:;; Can invalidate iterators, pointers and references, but only if the insert causes the load factor to be greater than the maximum load factor.
|
||||
Notes:;; Can invalidate iterators, pointers and references, but only if the insert causes the load to be greater than the maximum load.
|
||||
|
||||
---
|
||||
|
||||
@ -1170,6 +1165,19 @@ Effects:;; Does nothing, as the user is not allowed to change this parameter. Ke
|
||||
---
|
||||
|
||||
|
||||
==== max_load
|
||||
|
||||
```c++
|
||||
size_type max_load() const noexcept;
|
||||
```
|
||||
|
||||
[horizontal]
|
||||
Returns:;; The maximum number of elements the container can hold without rehashing, assuming that no further elements will be erased.
|
||||
Note:;; After construction, rehash or clearance, the container's maximum load is at least `max_load_factor() * bucket_count()`. This load will decrease by the number of elements inserted,
|
||||
but won't increase at the same rate on erasure.
|
||||
|
||||
---
|
||||
|
||||
==== rehash
|
||||
```c++
|
||||
void rehash(size_type n);
|
||||
|
1081
doc/unordered/unordered_flat_set.adoc
Normal file
@ -9,7 +9,7 @@
|
||||
|
||||
[listing,subs="+macros,+quotes"]
|
||||
-----
|
||||
// #include <boost/unordered_map.hpp>
|
||||
// #include <boost/unordered/unordered_map.hpp>
|
||||
|
||||
namespace boost {
|
||||
template<class Key,
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
[listing,subs="+macros,+quotes"]
|
||||
-----
|
||||
// #include <boost/unordered_map.hpp>
|
||||
// #include <boost/unordered/unordered_map.hpp>
|
||||
|
||||
namespace boost {
|
||||
template<class Key,
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
[listing,subs="+macros,+quotes"]
|
||||
-----
|
||||
// #include <boost/unordered_set.hpp>
|
||||
// #include <boost/unordered/unordered_set.hpp>
|
||||
|
||||
namespace boost {
|
||||
template<class Key,
|
||||
@ -276,7 +276,7 @@ Is identical to the difference type of `iterator` and `const_iterator`.
|
||||
typedef _implementation-defined_ iterator;
|
||||
----
|
||||
|
||||
An iterator whose value type is `value_type`.
|
||||
A constant iterator whose value type is `value_type`.
|
||||
|
||||
The iterator category is at least a forward iterator.
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
[listing,subs="+macros,+quotes"]
|
||||
-----
|
||||
// #include <boost/unordered_set.hpp>
|
||||
// #include <boost/unordered/unordered_set.hpp>
|
||||
|
||||
namespace boost {
|
||||
template<class Key,
|
||||
@ -278,7 +278,7 @@ Is identical to the difference type of `iterator` and `const_iterator`.
|
||||
typedef _implementation-defined_ iterator;
|
||||
----
|
||||
|
||||
An iterator whose value type is `value_type`.
|
||||
A constant iterator whose value type is `value_type`.
|
||||
|
||||
The iterator category is at least a forward iterator.
|
||||
|
||||
|