forked from MassiveAtoms/hashmap-bench
O P T I O N S
This commit is contained in:
8223
src/includes/3thparty/CLI11.hpp
Normal file
8223
src/includes/3thparty/CLI11.hpp
Normal file
File diff suppressed because it is too large
Load Diff
@@ -5,16 +5,15 @@
|
||||
#include "./tests.h"
|
||||
|
||||
vector<int> sizes = {
|
||||
50000, 100000, 150000, 200000, 250000, 300000, 350000, 400000, 500000,
|
||||
600000, 700000, 800000, 900000, 1000000,
|
||||
// 2000000, 3000000, 4000000, 5000000, 6000000, 7000000, 8000000, 9000000, 10000000,
|
||||
// 15000000, 20000000, 25000000, 30000000, 35000000, 40000000, 45000000, 50000000
|
||||
50000, 100000, 150000, 200000, 250000, 300000, 350000, 400000, 500000,
|
||||
600000, 700000, 800000, 900000, 1000000,
|
||||
// 2000000, 3000000, 4000000, 5000000, 6000000, 7000000, 8000000, 9000000, 10000000,
|
||||
// 15000000, 20000000, 25000000, 30000000, 35000000, 40000000, 45000000, 50000000
|
||||
};
|
||||
// to print type info
|
||||
|
||||
template <typename T>
|
||||
constexpr auto type_name()
|
||||
{
|
||||
template<typename T>
|
||||
constexpr auto type_name() {
|
||||
std::string_view name, prefix, suffix;
|
||||
#ifdef __clang__
|
||||
name = __PRETTY_FUNCTION__;
|
||||
@@ -32,73 +31,70 @@ constexpr auto type_name()
|
||||
name.remove_prefix(prefix.size());
|
||||
name.remove_suffix(suffix.size());
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
std::basic_string_view<char> name(T var){
|
||||
std::basic_string_view<char> name(T var) {
|
||||
return type_name<decltype(var)>();
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
void int_test_aggregate(T map, int runs){
|
||||
void int_test_aggregate(T map, int runs) {
|
||||
std::ofstream output{"results.csv", std::ios_base::app};
|
||||
for (int i = 0; i < runs; ++i){
|
||||
for (int i = 0; i < runs; ++i) {
|
||||
string insert = "\nint_insert, '";
|
||||
string succ_lookup = "\nint_succ_lookup, '";
|
||||
string nosucc_lookup = "\nint_nosucc_lookup, '";
|
||||
string delet = "\nint_delete, '";
|
||||
|
||||
insert += string{name(map)} + "'";
|
||||
succ_lookup += string{name(map)} + "'" ;
|
||||
nosucc_lookup += string{name(map)} +"'" ;
|
||||
delet += string{name(map)} + "'" ;
|
||||
for ( auto size : sizes){
|
||||
insert += string{name(map)} + "'";
|
||||
succ_lookup += string{name(map)} + "'";
|
||||
nosucc_lookup += string{name(map)} + "'";
|
||||
delet += string{name(map)} + "'";
|
||||
for (auto size : sizes) {
|
||||
vector<int> results = int_test(map, size);
|
||||
|
||||
|
||||
insert += ", " + std::to_string(results[0]);
|
||||
succ_lookup += ", " + std::to_string(results[1]);
|
||||
nosucc_lookup +=", " + std::to_string(results[2]);
|
||||
nosucc_lookup += ", " + std::to_string(results[2]);
|
||||
delet += ", " + std::to_string(results[3]);
|
||||
}
|
||||
output << insert << succ_lookup << nosucc_lookup << delet;
|
||||
cout << insert << succ_lookup << nosucc_lookup << delet;
|
||||
|
||||
output << insert << succ_lookup << nosucc_lookup << delet;
|
||||
cout << insert << succ_lookup << nosucc_lookup << delet;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<class T>
|
||||
void string_test_aggregate(T map, int runs){
|
||||
void string_test_aggregate(T map, int runs) {
|
||||
std::ofstream output{"results.csv", std::ios_base::app};
|
||||
for (int i = 0; i < runs; ++i){
|
||||
for (int i = 0; i < runs; ++i) {
|
||||
string insert = "\nint_insert, '";
|
||||
string succ_lookup = "\nint_succ_lookup, '";
|
||||
string nosucc_lookup = "\nint_nosucc_lookup, '";
|
||||
string delet = "\nint_delete, '";
|
||||
|
||||
insert += string{name(map)} + "'";
|
||||
succ_lookup += string{name(map)} + "'" ;
|
||||
nosucc_lookup += string{name(map)} +"'" ;
|
||||
delet += string{name(map)} + "'" ;
|
||||
for ( auto size : sizes){
|
||||
insert += string{name(map)} + "'";
|
||||
succ_lookup += string{name(map)} + "'";
|
||||
nosucc_lookup += string{name(map)} + "'";
|
||||
delet += string{name(map)} + "'";
|
||||
for (auto size : sizes) {
|
||||
vector<int> results = string_test(map, size);
|
||||
|
||||
|
||||
insert += ", " + std::to_string(results[0]);
|
||||
succ_lookup += ", " + std::to_string(results[1]);
|
||||
nosucc_lookup +=", " + std::to_string(results[2]);
|
||||
nosucc_lookup += ", " + std::to_string(results[2]);
|
||||
delet += ", " + std::to_string(results[3]);
|
||||
}
|
||||
output << insert << succ_lookup << nosucc_lookup << delet;
|
||||
cout << insert << succ_lookup << nosucc_lookup << delet;
|
||||
output << insert << succ_lookup << nosucc_lookup << delet;
|
||||
cout << insert << succ_lookup << nosucc_lookup << delet;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
@@ -3,10 +3,9 @@
|
||||
#define GENERATOR_H
|
||||
|
||||
|
||||
|
||||
|
||||
#include <random>
|
||||
#include <string>
|
||||
|
||||
static std::mt19937 generator(INT32_MAX - 2020);
|
||||
static std::uniform_int_distribution<int> insert_int(1, INT32_MAX * 0.875);
|
||||
static std::uniform_int_distribution<int> noninsert_int(INT32_MAX * 0.875, INT32_MAX);
|
||||
@@ -14,11 +13,12 @@ static std::uniform_int_distribution<int> singlechar(33, 123);
|
||||
|
||||
|
||||
int gen_int();
|
||||
|
||||
int gen_unsuccesfull_int();
|
||||
|
||||
std::string gen_string();
|
||||
|
||||
std::string gen_unsuccesfull_string();
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* GENERATOR_H */
|
@@ -24,27 +24,48 @@
|
||||
#include "./3thparty/parallel_hashmap/phmap.h"
|
||||
#include "./3thparty/emilib/hash_map.hpp"
|
||||
#include "3thparty/robinhood/robin_hood.h"
|
||||
#include <type_traits>
|
||||
|
||||
using std::string;
|
||||
using absl::Hash;
|
||||
using absl::Hash;
|
||||
|
||||
template<class T>
|
||||
void prepare(T& map, int size){
|
||||
void prepare(T& map, int size) {
|
||||
map.reserve(size);
|
||||
}
|
||||
|
||||
void prepare(google::sparse_hash_map<int, int>& map, int size){
|
||||
map.set_deleted_key(-1);
|
||||
void prepare(google::sparse_hash_map<int, int>& map, int size) {
|
||||
map.set_deleted_key(-1);
|
||||
}
|
||||
void prepare(google::sparse_hash_map<string, string>& map, int size){
|
||||
|
||||
void prepare(google::sparse_hash_map<string, string>& map, int size) {
|
||||
map.set_deleted_key("a");
|
||||
}
|
||||
void prepare(google::dense_hash_map<int, int>& map, int size){
|
||||
|
||||
void prepare(google::dense_hash_map<int, int>& map, int size) {
|
||||
map.set_empty_key(0);
|
||||
map.set_deleted_key(-1);
|
||||
}
|
||||
void prepare(google::dense_hash_map<string, string>& map, int size){
|
||||
|
||||
void prepare(google::dense_hash_map<string, string>& map, int size) {
|
||||
map.set_deleted_key("a");
|
||||
map.set_empty_key("");
|
||||
}
|
||||
|
||||
// with abseil hash
|
||||
void prepare(google::sparse_hash_map<int, int, Hash<int>>& map, int size) {
|
||||
map.set_deleted_key(-1);
|
||||
}
|
||||
|
||||
void prepare(google::sparse_hash_map<string, string, Hash<string>>& map, int size) {
|
||||
map.set_deleted_key("a");
|
||||
}
|
||||
|
||||
void prepare(google::dense_hash_map<int, int, Hash<int>>& map, int size) {
|
||||
map.set_empty_key(0);
|
||||
map.set_deleted_key(-1);
|
||||
}
|
||||
|
||||
void prepare(google::dense_hash_map<string, string, Hash<string>>& map, int size) {
|
||||
map.set_deleted_key("a");
|
||||
map.set_empty_key("");
|
||||
}
|
||||
|
@@ -19,8 +19,8 @@ using std::vector;
|
||||
using std::cout;
|
||||
|
||||
|
||||
template <class T>
|
||||
vector<int> int_test(T map, int size){
|
||||
template<class T>
|
||||
vector<int> int_test(T map, int size) {
|
||||
vector<int> results; // insert, lookup, unsuccesful lookup, delete times
|
||||
vector<int> sample_keys; // get a sample of keys to lookup and later delete
|
||||
|
||||
@@ -36,21 +36,21 @@ vector<int> int_test(T map, int size){
|
||||
prepare(testmap, size); // do special actions, such as setting the tombstone marker for other, more exotic hashmaps
|
||||
|
||||
{ // seperate scope, so all_keys gets destroyed. for good measure, empty it too
|
||||
vector<int> all_keys(size - 10000);
|
||||
std::generate(all_keys.begin(), all_keys.end(), gen_int);
|
||||
std::sample(all_keys.begin(), all_keys.end(), std::back_inserter(sample_keys), 10000, generator);
|
||||
vector<int> all_keys(size - 10000);
|
||||
std::generate(all_keys.begin(), all_keys.end(), gen_int);
|
||||
std::sample(all_keys.begin(), all_keys.end(), std::back_inserter(sample_keys), 10000, generator);
|
||||
|
||||
for (auto i : all_keys){
|
||||
testmap.insert({i,i});
|
||||
}
|
||||
all_keys.clear();
|
||||
for (auto i : all_keys) {
|
||||
testmap.insert({i, i});
|
||||
}
|
||||
all_keys.clear();
|
||||
}
|
||||
|
||||
|
||||
// testing vector access times to subtract later
|
||||
time_point<steady_clock> vector_start = steady_clock::now();
|
||||
for (auto i : sample_keys){
|
||||
if (i == -1 ) cout << "WTF"; // should never run, is here so loop doesnt get optimized away
|
||||
for (auto i : sample_keys) {
|
||||
if (i == -1) cout << "WTF"; // should never run, is here so loop doesnt get optimized away
|
||||
}
|
||||
time_point<steady_clock> vector_end = steady_clock::now();
|
||||
auto vector_acces_time = duration_cast<nanoseconds>(vector_end - vector_start);
|
||||
@@ -58,32 +58,32 @@ vector<int> int_test(T map, int size){
|
||||
|
||||
// insertion test
|
||||
time_point<steady_clock> insert_start = steady_clock::now();
|
||||
for (auto key : insert_keys){
|
||||
testmap.insert({key,key});
|
||||
for (auto key : insert_keys) {
|
||||
testmap.insert({key, key});
|
||||
}
|
||||
time_point<steady_clock> insert_end = steady_clock::now();
|
||||
|
||||
auto insert_time = (duration_cast<nanoseconds>(insert_end - insert_start) - vector_acces_time) / 10000 ;
|
||||
auto insert_time = (duration_cast<nanoseconds>(insert_end - insert_start) - vector_acces_time) / 10000;
|
||||
results.push_back(insert_time.count());
|
||||
// remove some memory
|
||||
insert_keys.clear();
|
||||
|
||||
// lookup test
|
||||
time_point<steady_clock> lookup_start = steady_clock::now();
|
||||
for (auto key : sample_keys){
|
||||
if (testmap[key] == 0) cout << "WTF";
|
||||
for (auto key : sample_keys) {
|
||||
if (testmap[key] == 0) cout << "WTF";
|
||||
}
|
||||
time_point<steady_clock> lookup_end = steady_clock::now();
|
||||
auto lookup_time = (duration_cast<nanoseconds>(lookup_end - lookup_start) - vector_acces_time)/10000;
|
||||
auto lookup_time = (duration_cast<nanoseconds>(lookup_end - lookup_start) - vector_acces_time) / 10000;
|
||||
results.push_back(lookup_time.count());
|
||||
|
||||
// unsuccesful lookup test
|
||||
time_point<steady_clock> unlookup_start = steady_clock::now();
|
||||
for (auto key : nonkeys){
|
||||
if (testmap[key] == -1) cout << "WTF";
|
||||
for (auto key : nonkeys) {
|
||||
if (testmap[key] == -1) cout << "WTF";
|
||||
}
|
||||
time_point<steady_clock> unlookup_end = steady_clock::now();
|
||||
auto unlookup_time = (duration_cast<nanoseconds>(unlookup_end - unlookup_start) - vector_acces_time) / 10000 ;
|
||||
auto unlookup_time = (duration_cast<nanoseconds>(unlookup_end - unlookup_start) - vector_acces_time) / 10000;
|
||||
results.push_back(unlookup_time.count());
|
||||
//free some memoru
|
||||
nonkeys.clear();
|
||||
@@ -91,10 +91,10 @@ vector<int> int_test(T map, int size){
|
||||
|
||||
// delete test
|
||||
time_point<steady_clock> delete_start = steady_clock::now();
|
||||
for (auto key : sample_keys){
|
||||
testmap.erase(key);
|
||||
for (auto key : sample_keys) {
|
||||
testmap.erase(key);
|
||||
}
|
||||
|
||||
|
||||
time_point<steady_clock> delete_end = steady_clock::now();
|
||||
auto delete_time = (duration_cast<nanoseconds>(delete_end - delete_start) - vector_acces_time) / 10000;
|
||||
results.push_back(delete_time.count());
|
||||
@@ -104,9 +104,8 @@ vector<int> int_test(T map, int size){
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class T>
|
||||
vector<int> string_test(T map, int size){
|
||||
template<class T>
|
||||
vector<int> string_test(T map, int size) {
|
||||
vector<int> results; // insert, lookup, unsuccesful lookup, delete times
|
||||
vector<string> sample_keys; // get a sample of keys to lookup and later delete
|
||||
|
||||
@@ -123,21 +122,21 @@ vector<int> string_test(T map, int size){
|
||||
prepare(testmap, size); // do special actions, such as setting the tombstone marker for other, more exotic hashmaps
|
||||
|
||||
{ // seperate scope, so all_keys gets destroyed. for good measure, empty it too
|
||||
vector<string> all_keys(size - 10000);
|
||||
std::generate(all_keys.begin(), all_keys.end(), gen_string);
|
||||
std::sample(all_keys.begin(), all_keys.end(), std::back_inserter(sample_keys), 10000, generator);
|
||||
vector<string> all_keys(size - 10000);
|
||||
std::generate(all_keys.begin(), all_keys.end(), gen_string);
|
||||
std::sample(all_keys.begin(), all_keys.end(), std::back_inserter(sample_keys), 10000, generator);
|
||||
|
||||
for (auto i : all_keys){
|
||||
testmap.insert({i,i});
|
||||
}
|
||||
all_keys.clear();
|
||||
for (auto i : all_keys) {
|
||||
testmap.insert({i, i});
|
||||
}
|
||||
all_keys.clear();
|
||||
}
|
||||
|
||||
|
||||
// testing vector access times to subtract later
|
||||
time_point<steady_clock> vector_start = steady_clock::now();
|
||||
for (auto i : sample_keys){
|
||||
if (i == "" ) cout << "WTF"; // should never run, is here so loop doesnt get optimized away
|
||||
for (auto i : sample_keys) {
|
||||
if (i == "") cout << "WTF"; // should never run, is here so loop doesnt get optimized away
|
||||
}
|
||||
time_point<steady_clock> vector_end = steady_clock::now();
|
||||
auto vector_acces_time = duration_cast<nanoseconds>(vector_end - vector_start);
|
||||
@@ -145,42 +144,42 @@ vector<int> string_test(T map, int size){
|
||||
|
||||
// insertion test
|
||||
time_point<steady_clock> insert_start = steady_clock::now();
|
||||
for (auto key : insert_keys){
|
||||
testmap.insert({key,key});
|
||||
for (auto key : insert_keys) {
|
||||
testmap.insert({key, key});
|
||||
}
|
||||
time_point<steady_clock> insert_end = steady_clock::now();
|
||||
|
||||
auto insert_time = (duration_cast<nanoseconds>(insert_end - insert_start) - vector_acces_time) / 10000 ;
|
||||
auto insert_time = (duration_cast<nanoseconds>(insert_end - insert_start) - vector_acces_time) / 10000;
|
||||
results.push_back(insert_time.count());
|
||||
// remove some memory
|
||||
insert_keys.clear();
|
||||
|
||||
// lookup test
|
||||
time_point<steady_clock> lookup_start = steady_clock::now();
|
||||
for (auto key : sample_keys){
|
||||
if (testmap[key] == "") cout << "WTF";
|
||||
for (auto key : sample_keys) {
|
||||
if (testmap[key] == "") cout << "WTF";
|
||||
}
|
||||
time_point<steady_clock> lookup_end = steady_clock::now();
|
||||
auto lookup_time = (duration_cast<nanoseconds>(lookup_end - lookup_start) - vector_acces_time)/10000;
|
||||
auto lookup_time = (duration_cast<nanoseconds>(lookup_end - lookup_start) - vector_acces_time) / 10000;
|
||||
results.push_back(lookup_time.count());
|
||||
|
||||
// unsuccesful lookup test
|
||||
time_point<steady_clock> unlookup_start = steady_clock::now();
|
||||
for (auto key : nonkeys){
|
||||
if (testmap[key] == "a") cout << "WTF";
|
||||
for (auto key : nonkeys) {
|
||||
if (testmap[key] == "a") cout << "WTF";
|
||||
}
|
||||
time_point<steady_clock> unlookup_end = steady_clock::now();
|
||||
auto unlookup_time = (duration_cast<nanoseconds>(unlookup_end - unlookup_start) - vector_acces_time) / 10000 ;
|
||||
auto unlookup_time = (duration_cast<nanoseconds>(unlookup_end - unlookup_start) - vector_acces_time) / 10000;
|
||||
results.push_back(unlookup_time.count());
|
||||
//free some memoru
|
||||
nonkeys.clear();
|
||||
|
||||
// delete test
|
||||
time_point<steady_clock> delete_start = steady_clock::now();
|
||||
for (auto key : sample_keys){
|
||||
testmap.erase(key);
|
||||
for (auto key : sample_keys) {
|
||||
testmap.erase(key);
|
||||
}
|
||||
|
||||
|
||||
time_point<steady_clock> delete_end = steady_clock::now();
|
||||
auto delete_time = (duration_cast<nanoseconds>(delete_end - delete_start) - vector_acces_time) / 10000;
|
||||
results.push_back(delete_time.count());
|
||||
|
Reference in New Issue
Block a user