diff --git a/CMakeLists.txt b/CMakeLists.txt index c5e7701..c94369d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -109,6 +109,8 @@ endif() if (PHMAP_BUILD_EXAMPLES) add_executable(basic examples/basic.cc) + add_executable(emplace examples/emplace.cc) + add_executable(hash_std examples/hash_std.cc) endif() diff --git a/examples/emplace.cc b/examples/emplace.cc new file mode 100644 index 0000000..c5a4554 --- /dev/null +++ b/examples/emplace.cc @@ -0,0 +1,124 @@ +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace patch +{ + template std::string to_string(const T& n) + { + std::ostringstream stm; + stm << n; + return stm.str(); + } +} + +template +using milliseconds = std::chrono::duration; + +class custom_type +{ + std::string one = "one"; + std::string two = "two"; + std::uint32_t three = 3; + std::uint64_t four = 4; + std::uint64_t five = 5; +public: + custom_type() = default; + // Make object movable and non-copyable + custom_type(custom_type &&) = default; + custom_type& operator=(custom_type &&) = default; + // should be automatically deleted per http://www.slideshare.net/ripplelabs/howard-hinnant-accu2014 + //custom_type(custom_type const&) = delete; + //custom_type& operator=(custom_type const&) = delete; +}; + +void test(std::size_t iterations, std::size_t container_size) +{ + std::clog << "bench: iterations: " << iterations << " / container_size: " << container_size << "\n"; + { + std::size_t count = 0; + auto t1 = std::chrono::high_resolution_clock::now(); + for (std::size_t i=0; i m; + m.reserve(container_size); + for (std::size_t j=0; j(t2 - t1).count(); + if (count != iterations*container_size) + std::clog << " invalid count: " << count << "\n"; + std::clog << " std::unordered_map: " << std::fixed << int(elapsed) << " ms\n"; + } + + { + std::size_t count = 0; + auto t1 = std::chrono::high_resolution_clock::now(); + for (std::size_t i=0; i m; + for (std::size_t j=0; j(t2 - t1).count(); + if (count != iterations*container_size) + std::clog << " invalid count: " << count << "\n"; + std::clog << " std::map: " << std::fixed << int(elapsed) << " ms\n"; + } + + { + std::size_t count = 0; + auto t1 = std::chrono::high_resolution_clock::now(); + for (std::size_t i=0; i> m; + m.reserve(container_size); + for (std::size_t j=0; j(t2 - t1).count(); + if (count != iterations*container_size) + std::clog << " invalid count: " << count << "\n"; + std::clog << " std::vector: " << std::fixed << int(elapsed) << " ms\n"; + } + + { + std::size_t count = 0; + auto t1 = std::chrono::high_resolution_clock::now(); + for (std::size_t i=0; i m; + m.reserve(container_size); + for (std::size_t j=0; j(t2 - t1).count(); + if (count != iterations*container_size) + std::clog << " invalid count: " << count << "\n"; + std::clog << " phmap::flat_hash_map: " << std::fixed << int(elapsed) << " ms\n"; + } + +} + +int main() +{ + std::size_t iterations = 100000; + + test(iterations,1); + test(iterations,10); + test(iterations,50); +} diff --git a/examples/hash_std.cc b/examples/hash_std.cc new file mode 100644 index 0000000..fdec8c8 --- /dev/null +++ b/examples/hash_std.cc @@ -0,0 +1,21 @@ +#include +#include + +#include "hash_std.h" // defines Person with std::hash specialization + +#include + +int main() +{ + // As we have defined a specialization of std::hash() for Person, + // we can now create sparse_hash_set or sparse_hash_map of Persons + // ---------------------------------------------------------------- + phmap::flat_hash_set persons = + { { "John", "Galt" }, + { "Jane", "Doe" } + }; + + for (auto& p: persons) + std::cout << p._first << ' ' << p._last << '\n'; + +} diff --git a/examples/hash_std.h b/examples/hash_std.h new file mode 100644 index 0000000..4fd8dfa --- /dev/null +++ b/examples/hash_std.h @@ -0,0 +1,36 @@ +#ifndef phmap_example_hash_std_ +#define phmap_example_hash_std_ + +#include + +using std::string; + +struct Person +{ + bool operator==(const Person &o) const + { + return _first == o._first && _last == o._last; + } + + string _first; + string _last; +}; + +namespace std +{ +// inject specialization of std::hash for Person into namespace std +// ---------------------------------------------------------------- + template<> + struct hash + { + std::size_t operator()(Person const &p) const + { + std::size_t seed = 0; + phmap::hash_combine(seed, p._first); + phmap::hash_combine(seed, p._last); + return seed; + } + }; +} + +#endif // phmap_example_hash_std_