uploaded current status

This commit is contained in:
joaquintides
2022-10-31 19:27:35 +01:00
parent 2068cf8d5b
commit 300f5554e5
87 changed files with 1359 additions and 112 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

View File

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

View File

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

View File

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 40 KiB

View File

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 37 KiB

BIN
doc/diagrams/buckets-oa.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -12,10 +12,10 @@
include::unordered/intro.adoc[] include::unordered/intro.adoc[]
include::unordered/buckets.adoc[] include::unordered/buckets.adoc[]
include::unordered/benchmarks.adoc[]
include::unordered/hash_equality.adoc[] include::unordered/hash_equality.adoc[]
include::unordered/comparison.adoc[] include::unordered/comparison.adoc[]
include::unordered/compliance.adoc[] include::unordered/compliance.adoc[]
include::unordered/benchmarks.adoc[]
include::unordered/rationale.adoc[] include::unordered/rationale.adoc[]
include::unordered/ref.adoc[] include::unordered/ref.adoc[]
include::unordered/changes.adoc[] include::unordered/changes.adoc[]

View File

@@ -4,27 +4,29 @@
= Benchmarks = 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 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 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. 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=] [caption=]
[cols="3*^.^a", frame=all, grid=all] [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-set/gcc/running insertion.xlsx.practice.png[width=250,link=../diagrams/benchmarks-set/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-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/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%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|non-duplicate elements
h|duplicate elements h|duplicate elements
@@ -36,9 +38,9 @@ max load factor 5
[cols="3*^.^a", frame=all, grid=all] [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-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/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-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/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 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, + h|non-duplicate elements, +
prior `reserve` prior `reserve`
@@ -50,15 +52,15 @@ prior `reserve`
|=== |===
=== Erasure ==== Erasure
[caption=] [caption=]
[cols="3*^.^a", frame=all, grid=all] [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-set/gcc/scattered%20erasure.xlsx.practice.png[width=250,link=../diagrams/benchmarks-set/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-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/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 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|non-duplicate elements
h|duplicate elements h|duplicate elements
@@ -66,15 +68,15 @@ h|duplicate elements +
max load factor 5 max load factor 5
|=== |===
=== Successful Lookup ==== Successful Lookup
[caption=] [caption=]
[cols="3*^.^a", frame=all, grid=all] [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-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/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-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/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 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|non-duplicate elements
h|duplicate elements h|duplicate elements
@@ -83,15 +85,15 @@ max load factor 5
|=== |===
=== Unsuccessful lookup ==== Unsuccessful lookup
[caption=] [caption=]
[cols="3*^.^a", frame=all, grid=all] [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-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/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-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/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 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|non-duplicate elements
h|duplicate elements h|duplicate elements
@@ -100,17 +102,17 @@ max load factor 5
|=== |===
== Clang 12 + libc++ === Clang 12 + libc++, x64
=== Insertion ==== Insertion
[caption=] [caption=]
[cols="3*^.^a", frame=all, grid=all] [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-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/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-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/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 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|non-duplicate elements
h|duplicate elements h|duplicate elements
@@ -123,9 +125,9 @@ max load factor 5
[cols="3*^.^a", frame=all, grid=all] [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-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/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-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/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 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, + h|non-duplicate elements, +
prior `reserve` prior `reserve`
@@ -137,15 +139,15 @@ prior `reserve`
|=== |===
=== Erasure ==== Erasure
[caption=] [caption=]
[cols="3*^.^a", frame=all, grid=all] [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-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/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-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/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 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|non-duplicate elements
h|duplicate elements h|duplicate elements
@@ -154,15 +156,15 @@ max load factor 5
|=== |===
=== Successful lookup ==== Successful lookup
[caption=] [caption=]
[cols="3*^.^a", frame=all, grid=all] [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-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/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-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/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 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|non-duplicate elements
h|duplicate elements h|duplicate elements
@@ -171,15 +173,15 @@ max load factor 5
|=== |===
=== Unsuccessful lookup ==== Unsuccessful lookup
[caption=] [caption=]
[cols="3*^.^a", frame=all, grid=all] [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-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/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-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/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 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|non-duplicate elements
h|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=] [caption=]
[cols="3*^.^a", frame=all, grid=all] [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-set/vs/running%20insertion.xlsx.practice.png[width=250,window=_blank,link=../diagrams/benchmarks-set/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-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/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 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|non-duplicate elements
h|duplicate elements h|duplicate elements
@@ -211,9 +213,9 @@ max load factor 5
[cols="3*^.^a", frame=all, grid=all] [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-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/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-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/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 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, + h|non-duplicate elements, +
prior `reserve` prior `reserve`
@@ -225,15 +227,15 @@ prior `reserve`
|=== |===
=== Erasure ==== Erasure
[caption=] [caption=]
[cols="3*^.^a", frame=all, grid=all] [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-set/vs/scattered%20erasure.xlsx.practice.png[width=250,window=_blank,link=../diagrams/benchmarks-set/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-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/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 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|non-duplicate elements
h|duplicate elements h|duplicate elements
@@ -242,15 +244,15 @@ max load factor 5
|=== |===
=== Successful lookup ==== Successful lookup
[caption=] [caption=]
[cols="3*^.^a", frame=all, grid=all] [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-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/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-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/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 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|non-duplicate elements
h|duplicate elements h|duplicate elements
@@ -259,15 +261,15 @@ max load factor 5
|=== |===
=== Unsuccessful lookup ==== Unsuccessful lookup
[caption=] [caption=]
[cols="3*^.^a", frame=all, grid=all] [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-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/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-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/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 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|non-duplicate elements
h|duplicate elements h|duplicate elements
@@ -275,3 +277,156 @@ h|duplicate elements, +
max load factor 5 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
|===

View File

@@ -5,6 +5,8 @@
= Bibliography = Bibliography
* _C/C++ Users Journal_. February, 2006. Pete Becker. http://www.ddj.com/cpp/184402066[STL and TR1: Part III - Unordered containers^]. + * _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^].

View File

@@ -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 If instead of `boost::unordered_set` we had used <<unordered_flat_set,`boost::unordered_flat_set`>>, the
diagram would look as follows: 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 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 (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 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, 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 adding 1,000 elements to a <<unordered_flat_map,`boost::unordered_flat_map`>> under high load
erasing those 1,000 elements will typically reduce the maximum load by around 160 rather conditions and then erasing 1,000 elements will typically reduce the maximum load by around
than restoring it to its original value. This is done internally by Boost.Unordered in order 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. 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 The maximum load will be reset to its theoretical maximum
(`max_load_factor() * bucket_count()`) right after `rehash`. (`max_load_factor() * bucket_count()`) right after `rehash`.

View File

@@ -7,9 +7,9 @@
== Closed-addressing containers: unordered_[multi]set, unordered_[multi]map == Closed-addressing containers: unordered_[multi]set, unordered_[multi]map
The intent of Boost.Unordered is to implement a close (but imperfect) The intent of Boost.Unordered is to provide a conformant
implementation of the {cpp}17 standard, that will work with {cpp}98 upwards. implementation of the {cpp}20 standard that will work with {cpp}98 upwards.
The wide compatibility does mean some comprimises have to be made. This wide compatibility does mean some compromises have to be made.
With a compiler and library that fully support {cpp}11, the differences should With a compiler and library that fully support {cpp}11, the differences should
be minor. 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. * `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. * 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, * 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.

View File

@@ -17,7 +17,7 @@ has a good summary of the implementation issues for hash tables in general.
=== Data Structure === Data Structure
By specifying an interface for accessing the buckets of the container the 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 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 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 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 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. 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. 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 === Number of Buckets
@@ -89,8 +89,8 @@ We discuss here the most relevant principles.
Given its rich functionality and cross-platform interoperability, 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`. `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 As it happens, `boost::hash` for integral and other basic types does not possess
the good statistical properties required by open addressing; to cope with this, the statistical properties required by open addressing; to cope with this,
we implement a post-mixing stage: we implement a post-mixing stage:
* 64-bit architectures: we use the `xmx` function defined in * 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^] 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, 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 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.

View File

@@ -7,3 +7,4 @@ include::unordered_set.adoc[]
include::unordered_multiset.adoc[] include::unordered_multiset.adoc[]
include::hash_traits.adoc[] include::hash_traits.adoc[]
include::unordered_flat_map.adoc[] include::unordered_flat_map.adoc[]
include::unordered_flat_set.adoc[]

View File

@@ -145,12 +145,6 @@ namespace boost {
template<class M> template<class M>
iterator xref:#unordered_flat_map_insert_or_assign_with_hint[insert_or_assign](const_iterator hint, key_type&& k, M&& obj); 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](iterator position);
void xref:#unordered_flat_map_erase_by_position[erase](const_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); 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_load_factor[load_factor]() const noexcept;
float xref:#unordered_flat_map_max_load_factor[max_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); 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_rehash[rehash](size_type n);
void xref:#unordered_flat_map_reserve[reserve](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`. |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_ |_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_ |_Allocator_
|An allocator whose value type is the same as the container's value type. |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 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 `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 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 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 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 ==== Bucket Count Constructor
```c++ ```c++
explicit unordered_flat_map(size_type n, explicit unordered_flat_map(size_type n,
const hasher& hf = hasher(), const hasher& hf = hasher(),
const key_equal& eql = key_equal(), const key_equal& eql = key_equal(),
const allocator_type& a = allocator_type()); const allocator_type& a = allocator_type());
``` ```
Constructs an empty container with at least `n` buckets, using `hf` as the hash Constructs an empty container with at least `n` buckets, using `hf` as the hash
@@ -563,7 +558,7 @@ const_iterator begin() const noexcept;
[horizontal] [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. 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] [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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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] [horizontal]
Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] into the container from `*first`. 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. 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] [horizontal]
Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] into the container from `*first`. 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. 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. 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. 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. 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. 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] [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. 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. 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. Erases all elements in the container.
[horizontal] [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())`. 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`. 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. 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 ==== rehash
```c++ ```c++
void rehash(size_type n); void rehash(size_type n);

File diff suppressed because it is too large Load Diff

View File

@@ -9,7 +9,7 @@
[listing,subs="+macros,+quotes"] [listing,subs="+macros,+quotes"]
----- -----
// #include <boost/unordered_map.hpp> // #include <boost/unordered/unordered_map.hpp>
namespace boost { namespace boost {
template<class Key, template<class Key,

View File

@@ -9,7 +9,7 @@
[listing,subs="+macros,+quotes"] [listing,subs="+macros,+quotes"]
----- -----
// #include <boost/unordered_map.hpp> // #include <boost/unordered/unordered_map.hpp>
namespace boost { namespace boost {
template<class Key, template<class Key,

View File

@@ -9,7 +9,7 @@
[listing,subs="+macros,+quotes"] [listing,subs="+macros,+quotes"]
----- -----
// #include <boost/unordered_set.hpp> // #include <boost/unordered/unordered_set.hpp>
namespace boost { namespace boost {
template<class Key, template<class Key,
@@ -276,7 +276,7 @@ Is identical to the difference type of `iterator` and `const_iterator`.
typedef _implementation-defined_ 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. The iterator category is at least a forward iterator.

View File

@@ -9,7 +9,7 @@
[listing,subs="+macros,+quotes"] [listing,subs="+macros,+quotes"]
----- -----
// #include <boost/unordered_set.hpp> // #include <boost/unordered/unordered_set.hpp>
namespace boost { namespace boost {
template<class Key, template<class Key,
@@ -278,7 +278,7 @@ Is identical to the difference type of `iterator` and `const_iterator`.
typedef _implementation-defined_ 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. The iterator category is at least a forward iterator.