Skip to content

Instantly share code, notes, and snippets.

@BarclayII
Last active March 24, 2024 10:51
Show Gist options
  • Save BarclayII/e8705d1d7acfbb839fac9cbf9d6643fe to your computer and use it in GitHub Desktop.
Save BarclayII/e8705d1d7acfbb839fac9cbf9d6643fe to your computer and use it in GitHub Desktop.
C++ unordered_map, ordered_map, and custom hashmap comparison (compile with -O2)
#include <unordered_map>
#include <map>
#include <vector>
#include <iostream>
#include <utility>
#include <cstdint>
#include <ctime>
#include <cstdlib>
using std::uint64_t;
using std::time;
using std::clock;
using std::srand;
using std::rand;
typedef std::pair<uint64_t, uint64_t> IdPair;
inline size_t hash(uint64_t a, uint64_t b)
{
uint64_t h1 = (a + 0x3333333333333333) * 0x1f1f1f1f1f1f1f1f;
uint64_t h2 = (b + 0xcccccccccccccccc) * 0x0f0f0f0f0f0f0f0f;
return (size_t)(h1 ^ h2);
}
struct IdPairHash {
public:
size_t operator () (const IdPair &p) const {
return hash(p.first, p.second);
}
};
struct IdPairVector {
uint64_t u;
uint64_t v;
std::vector<uint64_t> e;
};
typedef std::unordered_map<IdPair, std::vector<uint64_t>, IdPairHash> EdgeMap;
typedef std::map<IdPair, std::vector<uint64_t>> EdgeOrderedMap;
typedef std::vector<std::vector<IdPairVector>> EdgeMapV;
#define T 5000000
#define N 1000000
int main(void)
{
EdgeMap e;
EdgeOrderedMap em;
EdgeMapV ev(N);
clock_t t0, t1;
int n = 0;
srand(time(NULL));
t0 = clock();
for (int i = 0; i < T; ++i) {
uint64_t u = rand() % N;
uint64_t v = rand() % N;
std::vector<uint64_t> &w = e[std::make_pair(u, v)];
w.push_back(i);
}
t1 = clock();
std::cout << t1 - t0 << std::endl;
t0 = clock();
for (int i = 0; i < T; ++i) {
uint64_t u = rand() % N;
uint64_t v = rand() % N;
std::vector<uint64_t> &w = em[std::make_pair(u, v)];
w.push_back(i);
}
t1 = clock();
std::cout << t1 - t0 << std::endl;
t0 = clock();
for (int i = 0; i < T; ++i) {
uint64_t u = rand() % N;
uint64_t v = rand() % N;
size_t h = hash(u, v) % N;
int flag = 0;
for (auto &it : ev[h]) {
if (it.u == u && it.v == v) {
it.e.push_back(i);
flag = 1;
break;
}
}
if (!flag) {
ev[h].emplace_back();
IdPairVector &pv = ev[h].back();
pv.u = u;
pv.v = v;
pv.e.push_back(i);
}
}
t1 = clock();
std::cout << t1 - t0 << std::endl;
n = 0;
t0 = clock();
for (int i = 0; i < T; ++i) {
uint64_t u = rand() % N;
uint64_t v = rand() % N;
n += (e.find(std::make_pair(u, v)) != e.end());
}
t1 = clock();
std::cout << n << ' ' << t1 - t0 << std::endl;
n = 0;
t0 = clock();
for (int i = 0; i < T; ++i) {
uint64_t u = rand() % N;
uint64_t v = rand() % N;
n += (em.find(std::make_pair(u, v)) != em.end());
}
t1 = clock();
std::cout << n << ' ' << t1 - t0 << std::endl;
n = 0;
t0 = clock();
for (int i = 0; i < T; ++i) {
uint64_t u = rand() % N;
uint64_t v = rand() % N;
size_t h = hash(u, v) % N;
int flag = 0;
for (auto &it : ev[h]) {
if (it.u == u && it.v == v) {
flag = 1;
break;
}
}
n += flag;
}
t1 = clock();
std::cout << n << ' ' << t1 - t0 << std::endl;
return 0;
}
// Result:
// 2819856
// 5737226
// 1507289
// 25 1358670
// 23 5403166
// 26 811926
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment