Files
hashmap-bench/src/includes/tests.h
TinyAtoms 64adaa9be1 works
2020-02-05 13:56:39 -03:00

207 lines
6.7 KiB
C++

#ifndef TESTS_H
#define TESTS_H
#include <vector>
#include <algorithm>
#include <iterator>
#include <chrono>
// maps
#include <sparsehash/sparse_hash_map>
// own
#include "./generator.h"
using namespace std::chrono;
using std::vector;
using std::string;
using std::cout;
// since my testing is based on this function, this one doesn't need no prep
void prepare(std::unordered_map<int, int>& map,int size){
map.reserve(size);
return;
}
void prepare(std::unordered_map<string, string>& map,int size){
map.reserve(size);
return;
}
void prepare(google::sparse_hash_map<int, int>& map, int size){
map.set_deleted_key(0);
return;
}
template <class T>
vector<float> int_test(T testmap, int size){
vector<float> results; // insert, lookup, unsuccesful lookup, delete times
vector<int> sample_keys; // get a sample of keys to lookup and later delete
// unsuccesful lookup keys
vector<int> nonkeys(10000);
std::generate(nonkeys.begin(), nonkeys.end(), gen_unsuccesfull_int);
// keys for insert test
vector<int> insert_keys(10000);
std::generate(insert_keys.begin(), insert_keys.end(), gen_int);
// T testmap {};
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);
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
}
time_point<steady_clock> vector_end = steady_clock::now();
auto vector_acces_time = duration_cast<nanoseconds>(vector_end - vector_start);
// insertion test
time_point<steady_clock> insert_start = steady_clock::now();
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 ;
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";
}
time_point<steady_clock> lookup_end = steady_clock::now();
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";
}
time_point<steady_clock> unlookup_end = steady_clock::now();
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);
}
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());
return results;
}
template <class T>
vector<float> string_test(T map, int size){
vector<float> results; // insert, lookup, unsuccesful lookup, delete times
vector<string> sample_keys; // get a sample of keys to lookup and later delete
// unsuccesful lookup keys
vector<string> nonkeys(10000);
std::generate(nonkeys.begin(), nonkeys.end(), gen_unsuccesfull_string);
// keys for insert test
vector<string> insert_keys(10000);
std::generate(insert_keys.begin(), insert_keys.end(), gen_string);
T testmap {};
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);
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
}
time_point<steady_clock> vector_end = steady_clock::now();
auto vector_acces_time = duration_cast<nanoseconds>(vector_end - vector_start);
// insertion test
time_point<steady_clock> insert_start = steady_clock::now();
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 ;
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";
}
time_point<steady_clock> lookup_end = steady_clock::now();
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] == "") 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 ;
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);
}
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());
return results;
}
#endif /* TESTS_H */