Skip to content

Instantly share code, notes, and snippets.

@ahamez
Created August 30, 2014 13:40
Show Gist options
  • Save ahamez/0bcaee5aab1d849f7e23 to your computer and use it in GitHub Desktop.
Save ahamez/0bcaee5aab1d849f7e23 to your computer and use it in GitHub Desktop.
sdd::mem::hash_table comparison with boost::intrusive::unordered_set and std::unordered_set
#include <chrono>
#include <iostream>
#include <memory>
#include <unordered_set>
#include <vector>
#include <boost/intrusive/unordered_set.hpp>
#include <sdd/mem/hash_table.hh>
#include <sdd/util/hash.hh>
#include <sdd/util/next_power.hh>
class timer
{
private:
std::chrono::time_point<std::chrono::system_clock> start_;
public:
timer()
: start_(std::chrono::system_clock::now())
{}
void
reset()
{
start_ = std::chrono::system_clock::now();
}
std::chrono::duration<double>
duration()
{
return std::chrono::system_clock::now() - start_;
}
};
struct foo1
{
sdd::mem::intrusive_member_hook<foo1> hook;
int i_;
int j_;
foo1(int i, int j) : i_(i), j_(j) {}
bool operator==(const foo1& other) const noexcept {return i_ == other.i_ and j_ == other.j_;}
};
struct foo2
{
int i_;
int j_;
foo2(int i, int j) : i_(i), j_(j) {}
bool operator==(const foo2& other) const noexcept {return i_ == other.i_ and j_ == other.j_;}
};
struct foo3
: public boost::intrusive::unordered_set_base_hook<boost::intrusive::link_mode<boost::intrusive::normal_link>>
{
int i_;
int j_;
foo3(int i, int j) : i_(i), j_(j) {}
bool operator==(const foo3& other) const noexcept {return i_ == other.i_ and j_ == other.j_;}
};
namespace std
{
template <>
struct hash<foo1>
{
std::size_t
operator()(const foo1& f)
const noexcept
{
using namespace sdd::hash;
return seed(f.i_) ((val(f.j_)));
}
};
template <>
struct hash<foo2>
{
std::size_t
operator()(const foo2& f)
const noexcept
{
using namespace sdd::hash;
return seed(f.i_) ((val(f.j_)));
}
};
template <>
struct hash<foo3>
{
std::size_t
operator()(const foo3& f)
const noexcept
{
using namespace sdd::hash;
return seed(f.i_) ((val(f.j_)));
}
};
}
int main()
{
const auto max = 10'000'000ul;
{
sdd::mem::hash_table<foo1, true> ht(1'000'000);
std::vector<std::shared_ptr<foo1>> vec;
vec.reserve(max);
for (auto i = 0ul; i < max; ++i)
{
vec.emplace_back(std::make_shared<foo1>(i, i+2));
}
timer t;
for (auto&& entry : vec)
{
ht.insert(*entry);
}
std::cout << t.duration().count() << '\n';
std::cout << ht.size() << '\n';
}
{
std::unordered_set<foo2> us;
us.reserve(1'000'000);
timer t;
for (auto i = 0ul; i < max; ++i)
{
us.emplace(i, i+2);
}
std::cout << t.duration().count() << '\n';
std::cout << us.size() << '\n';
}
{
std::vector<std::shared_ptr<foo3>> vec;
vec.reserve(max);
for (auto i = 0ul; i < max; ++i)
{
vec.emplace_back(std::make_shared<foo3>(i, i+2));
}
using bucket_type = boost::intrusive::unordered_set<foo3>::bucket_type;
using bucket_traits = boost::intrusive::unordered_set<foo3>::bucket_traits;
const auto nb_buckets = sdd::util::next_power_of_2(1'000'000ul);
std::unique_ptr<bucket_type[]> buckets_ptr(new bucket_type[nb_buckets]);
using set_type = boost::intrusive::unordered_set<foo3
, boost::intrusive::hash<std::hash<foo3>>
, boost::intrusive::power_2_buckets<true>>;
set_type set(bucket_traits(buckets_ptr.get(), nb_buckets));
timer t;
for (auto&& entry : vec)
{
set.insert(*entry);
}
std::cout << t.duration().count() << '\n';
std::cout << set.size() << '\n';
}
return 0;
}
// $ clang++ -std=c++1y -stdlib=libc++ -lboost_system -lboost_context -lboost_coroutine -lboost_thread -L /usr/local/boost-1.56/lib hash.cc -I ~/code/libsdd -I /usr/local/boost-1.56/include -O3 -DNDEBUG
//
// [~/Desktop] 15:36:32
// $ ./a.out
// 0.884235
// 10000000
// 4.30367
// 10000000
// 1.16752
// 10000000
// $ g++-mp-4.9 -std=c++1y -lboost_system -lboost_context -lboost_coroutine -lboost_thread -L /usr/local/boost-1.56/lib hash.cc -I ~/code/libsdd -I /usr/local/boost-1.56/include -O3 -DNDEBUG
//
// [~/Desktop] 15:36:57
// $ ./a.out
// 0.693119
// 10000000
// 3.93413
// 10000000
// 1.05133
// 10000000
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment