#ifndef TESTS_H #define TESTS_H #include #include #include #include // maps #include // 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& map,int size){ map.reserve(size); return; } void prepare(std::unordered_map& map,int size){ map.reserve(size); return; } void prepare(google::sparse_hash_map& map, int size){ map.set_deleted_key(0); return; } template vector int_test(T testmap, int size){ vector results; // insert, lookup, unsuccesful lookup, delete times vector sample_keys; // get a sample of keys to lookup and later delete // unsuccesful lookup keys vector nonkeys(10000); std::generate(nonkeys.begin(), nonkeys.end(), gen_unsuccesfull_int); // keys for insert test vector 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 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 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 vector_end = steady_clock::now(); auto vector_acces_time = duration_cast(vector_end - vector_start); // insertion test time_point insert_start = steady_clock::now(); for (auto key : insert_keys){ testmap.insert({key,key}); } time_point insert_end = steady_clock::now(); auto insert_time = (duration_cast(insert_end - insert_start) - vector_acces_time) / 10000 ; results.push_back(insert_time.count()); // remove some memory insert_keys.clear(); // lookup test time_point lookup_start = steady_clock::now(); for (auto key : sample_keys){ if (testmap[key] == 0) cout << "WTF"; } time_point lookup_end = steady_clock::now(); auto lookup_time = (duration_cast(lookup_end - lookup_start) - vector_acces_time)/10000; results.push_back(lookup_time.count()); // unsuccesful lookup test time_point unlookup_start = steady_clock::now(); for (auto key : nonkeys){ if (testmap[key] == -1) cout << "WTF"; } time_point unlookup_end = steady_clock::now(); auto unlookup_time = (duration_cast(unlookup_end - unlookup_start) - vector_acces_time) / 10000 ; results.push_back(unlookup_time.count()); //free some memoru nonkeys.clear(); // delete test time_point delete_start = steady_clock::now(); for (auto key : sample_keys){ testmap.erase(key); } time_point delete_end = steady_clock::now(); auto delete_time = (duration_cast(delete_end - delete_start) - vector_acces_time) / 10000; results.push_back(delete_time.count()); return results; } template vector string_test(T map, int size){ vector results; // insert, lookup, unsuccesful lookup, delete times vector sample_keys; // get a sample of keys to lookup and later delete // unsuccesful lookup keys vector nonkeys(10000); std::generate(nonkeys.begin(), nonkeys.end(), gen_unsuccesfull_string); // keys for insert test vector 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 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 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 vector_end = steady_clock::now(); auto vector_acces_time = duration_cast(vector_end - vector_start); // insertion test time_point insert_start = steady_clock::now(); for (auto key : insert_keys){ testmap.insert({key,key}); } time_point insert_end = steady_clock::now(); auto insert_time = (duration_cast(insert_end - insert_start) - vector_acces_time) / 10000 ; results.push_back(insert_time.count()); // remove some memory insert_keys.clear(); // lookup test time_point lookup_start = steady_clock::now(); for (auto key : sample_keys){ if (testmap[key] == "") cout << "WTF"; } time_point lookup_end = steady_clock::now(); auto lookup_time = (duration_cast(lookup_end - lookup_start) - vector_acces_time)/10000; results.push_back(lookup_time.count()); // unsuccesful lookup test time_point unlookup_start = steady_clock::now(); for (auto key : nonkeys){ if (testmap[key] == "") cout << "WTF"; } time_point unlookup_end = steady_clock::now(); auto unlookup_time = (duration_cast(unlookup_end - unlookup_start) - vector_acces_time) / 10000 ; results.push_back(unlookup_time.count()); //free some memoru nonkeys.clear(); // delete test time_point delete_start = steady_clock::now(); for (auto key : sample_keys){ testmap.erase(key); } time_point delete_end = steady_clock::now(); auto delete_time = (duration_cast(delete_end - delete_start) - vector_acces_time) / 10000; results.push_back(delete_time.count()); return results; } #endif /* TESTS_H */