• Stars
    star
    183
  • Rank 203,420 (Top 5 %)
  • Language
    C++
  • License
    MIT License
  • Created over 8 years ago
  • Updated 8 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

An open addressing linear probing hash table, tuned for delete heavy workloads

HashMap.h

C/C++ CI Build Status License

A hash table mostly compatible with the C++11 std::unordered_map interface, but with much higher performance for many workloads.

Implementation

This hash table uses open addressing with linear probing and backshift deletion. Open addressing and linear probing minimizes memory allocations and achieves high cache efficiency. Backshift deletion keeps performance high for delete heavy workloads by not clobbering the hash table with tombestones.

Usage

HashMap is mostly compatible with the C++11 container interface. The main differences are:

  • A key value to represent the empty key is required.
  • Key and T needs to be default constructible.
  • Iterators are invalidated on all modifying operations.
  • It's invalid to perform any operations with the empty key.
  • Destructors are not called on erase.
  • Extensions for lookups using related key types.

Member functions:

  • HashMap(size_type bucket_count, key_type empty_key);

    Construct a HashMap with bucket_count buckets and empty_key as the empty key.

The rest of the member functions are implemented as for std::unordered_map.

Example

  using namespace rigtorp;

  // Hash for using std::string as lookup key
  struct Hash {
    size_t operator()(int v) { return v * 7; }
    size_t operator()(const std::string &v) { return std::stoi(v) * 7; }
  };

  // Equal comparison for using std::string as lookup key
  struct Equal {
    bool operator()(int lhs, int rhs) { return lhs == rhs; }
    bool operator()(int lhs, const std::string &rhs) {
      return lhs == std::stoi(rhs);
    }
  };

  // Create a HashMap with 16 buckets and 0 as the empty key
  HashMap<int, int, Hash, Equal> hm(16, 0);
  hm.emplace(1, 1);
  hm[2] = 2;

  // Iterate and print key-value pairs
  for (const auto &e : hm) {
    std::cout << e.first << " = " << e.second << "\n";
  }

  // Lookup using std::string
  std::cout << hm.at("1") << "\n";

  // Erase entry
  hm.erase(1);

Benchmark

A benchmark src/HashMapBenchmark.cpp is included with the sources. The benchmark simulates a delete heavy workload where items are repeatedly inserted and deleted.

I ran this benchmark on the following configuration:

  • AMD Ryzen 9 3900X
  • Linux 5.8.4-200.fc32.x86_64
  • gcc (GCC) 10.2.1 20200723 (Red Hat 10.2.1-1)
  • Isolated a core complex (CCX) using isolcpus for running the benchmark

When working set fits in L3 cache (HashMapBenchmark -c 100000 -i 100000000):

Implementation mean ns/iter max ns/iter
HashMap 24 1082
absl::flat_hash_map 24 2074
google::dense_hash_map 49 689846
std::unordered_map 67 10299

When working set is larger than L3 cache (HashMapBenchmark -c 10000000 -i 1000000000):

Implementation mean ns/iter max ns/iter
HashMap 75 19026
absl::flat_hash_map 101 19848
google::dense_hash_map 111 226083255
std::unordered_map 408 22422

Cited by

HashMap has been cited by the following papers:

About

This project was created by Erik Rigtorp <[email protected]>.

More Repositories

1

awesome-modern-cpp

A collection of resources on modern C++
HTML
11,209
star
2

awesome-lockfree

A collection of resources on wait-free and lock-free programming
1,634
star
3

MPMCQueue

A bounded multi-producer multi-consumer concurrent queue written in C++11
C++
1,048
star
4

SPSCQueue

A bounded single-producer single-consumer wait-free and lock-free queue written in C++11
C++
800
star
5

ipc-bench

Latency benchmarks of Unix IPC mechanisms
C
531
star
6

spartan

A collection of High-Frequency trading components
C++
250
star
7

udpreplay

Replay UDP packets from a pcap file
C++
242
star
8

Seqlock

An implementation of Seqlock in C++11
C++
167
star
9

nanomq

Ultra low latency messaging kernel
C++
151
star
10

c2clat

A tool to measure CPU core to core latency
C++
104
star
11

hiccups

Measures the system induced jitter ("hiccups") a CPU bound thread experiences
C++
85
star
12

efvicap

erfvicap is a packet capture tool for network adapters from Solarflare
C++
53
star
13

statkit

Statistics toolkit for JavaScript
JavaScript
51
star
14

Function

Heap allocation free version of C++11 std::function
C++
49
star
15

TokenBucket

Lock-free implementation of the token bucket algorithm in C++
C++
44
star
16

isatomic

Test if AVX vector loads and stores are atomic
C++
20
star
17

CharConv

Fast integer to string and string to integer conversion functions
C++
16
star
18

BinarySemaphore

Binary semaphore using futexes.
C++
8
star
19

RingMap

Hybrid data structure that acts like a ring buffer and map
C++
7
star
20

dotemacs

My emacs config
Emacs Lisp
6
star
21

unats

A simple single threaded NATS client for C++.
C++
4
star
22

nordpool

Data preprocessing / munging scripts for Nordpool power market data
HTML
3
star
23

openonload

git import of https://www.openonload.org/
Shell
3
star
24

go-pikchr

Pikchr wrapped for Go using WebAssembly. No cgo required.
Go
3
star
25

sfpl

Simple functional programming language
Python
2
star
26

spark-dht11

Spark app to read a DHT11 sensor and publish humidity and temperature as Spark variables
C++
2
star
27

gmbackup

Simple tool to backup a Gmail account
Go
2
star
28

t-amp

Tripath Class-T audio amplifier
1
star
29

anything-git

Anything sources for Git
Emacs Lisp
1
star
30

go-graphviz

Graphviz wrapped for Go using WebAssembly. No cgo required.
CMake
1
star
31

chipamp

A hand crafted power amplifier of the Gainclone type
1
star
32

sysjitter2

1
star
33

gccsense

Fork of http://cx4a.org/repo/gccsense.git
Emacs Lisp
1
star