PrevNext
Rare
 0/2

(Optional) A Faster Hash Table in C++

Author: Benjamin Qi

Introduces gp_hash_table.

Resources
CF

Introduces gp_hash_table

GCC

documentation

Benq (from KACTL)

Read / writes are much faster than unordered_map. Its actual size is always a power of 2. The documentation is rather confusing, so I'll just summarize the most useful functions here.

#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;

Unordered Set

gp_hash_table<K,null_type> functions similarly to unordered_set<K>.

Hacking

gp_hash_table is also vulnerable to hacking. The hash function mentioned in the blog:

const int RANDOM = chrono::high_resolution_clock::now().time_since_epoch().count();
struct chash {
int operator()(int x) const { return x ^ RANDOM; }
};
gp_hash_table<key, int, chash> table;

is easily hackable (see neal's comment). To avoid this, we can replace chash with one of the custom hash functions mentioned previously.

Resizing

Unordered map has reserve. Calling this function before inserting any elements can result in a constant factor speedup.

We can modify the declaration of gp_hash_table so that it supports the resize function, which operates similarly.

template<class K,class V> using ht = gp_hash_table<
K,
null_type,
hash<K>,
equal_to<K>,
direct_mask_range_hashing<>,
linear_probe_fn<>,
hash_standard_resize_policy<
hash_exponential_size_policy<>,
hash_load_check_resize_trigger<>,
true
>
>;

These are the same template arguments as the default gp_hash_table, except false has been changed to true. This modification allows us to change the actual size of the hash table.

int main() {
ht<int,null_type> g; g.resize(5);
cout << g.get_actual_size() << "\n"; // 8
cout << g.size() << "\n"; // 0
}

When calling g.resize(x), x is rounded up to the nearest power of 2. Then the actual size of g is changed to be equal to x (unless x < g.size(), in which case an error is thrown).

Resources
GCC

documentation

Furthermore, if we construct g with the following arguments:

ht<int,null_type> g({},{},{},{},{1<<16});

then the actual size of g is always at least 1<<16 (regardless of calls to resize). The last argument must be a power of 2 (or else errors will be thrown).

Solving 3SUM

Focus Problem – read through this problem before continuing!

Since all the values are quite small, you can use an array instead of a hashmap. But if you didn't read the constraints carefully enough, you're in luck!

Solution

Problems

StatusSourceProblem NameDifficultyTags
CSESNormal
Show TagsSet

Module Progress:

PrevNext