#include <iostream>
#include <vector>
#include <string>
#include <random>
#include <unordered_map>
#include <chrono>
#include <algorithm>
#include <functional>
using namespace std;
struct Foo
{
std::size_t hash;
std::string name;
};
std::vector<Foo> generate_random_vec(std::size_t SIZE)
{
const char alphanumeric[] = " 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
std::default_random_engine rng;
std::uniform_int_distribution<> dist (0, sizeof(alphanumeric) - 2);
std::vector<Foo> result;
result.resize(SIZE);
std::random_device rd;
std::mt19937 mt(rd());
std::uniform_int_distribution<int> dist_string_length(4, 32);
for (std::size_t count = 0; count < SIZE; ++count)
{
std::string str;
for (uint8_t i = 0; i < dist_string_length(mt); ++i)
{
str += alphanumeric[dist(rng)];
}
Foo obj;
obj.name = std::move(str);
result[count] = obj;
}
return result;
}
struct OrderFooByNameHash
{
inline bool operator () ( const Foo& _left, const Foo& _right )
{
return _left.hash < _right.hash;
}
inline bool operator () ( const std::hash<std::string>::result_type& _left, const Foo& _right ) const
{
return _left < _right.hash;
}
inline bool operator () ( const Foo& _left, const std::hash<std::string>::result_type& _right ) const
{
return _left.hash < _right;
}
};
int main() {
Foo obj_find = {0, "String to find"};
obj_find.hash = std::hash<std::string>()(obj_find.name);
std::vector<Foo> vec_string = generate_random_vec(100000);
std::unordered_map<std::string,int> stringToMap;
vec_string.push_back(obj_find);
std::hash<std::string> hash_fn;
for (auto& itr : vec_string)
itr.hash = hash_fn(itr.name);
for (auto itr : vec_string)
stringToMap.emplace(itr.name, 1);
std::sort( vec_string.begin(), vec_string.end(), OrderFooByNameHash());
//for (auto itr : vec_string)
// std::cout << itr.name << std::endl;
//for (auto itr : stringToMap)
// std::cout << itr.first << std::endl;
bool found_string = false;
std::size_t RUN_COUNT = 500000;
const auto startTime_1 = chrono::high_resolution_clock::now();
for (int count = 0; count < RUN_COUNT; ++count)
{
auto itr = std::lower_bound( vec_string.begin(), vec_string.end(), obj_find.hash, OrderFooByNameHash());
for (; itr != vec_string.end(); ++itr)
{
if ((*itr).hash != obj_find.hash)
break;
if ((*itr).name == obj_find.name)
{
int i = 0;
}
}
}
chrono::high_resolution_clock::duration elapsedTime_1 = chrono::high_resolution_clock::now() - startTime_1;
std::cout << "sorted_vector Time: " << chrono::duration_cast<chrono::milliseconds>(elapsedTime_1).count() << " ms" << std::endl;
const auto startTime_2 = chrono::high_resolution_clock::now();
for (int count = 0; count < RUN_COUNT; ++count)
{
const auto startTime = chrono::high_resolution_clock::now();
auto itr = stringToMap.find(obj_find.name);
if (itr != stringToMap.end() && itr->first == obj_find.name)
{
int i = 0;
}
}
chrono::high_resolution_clock::duration elapsedTime_2 = chrono::high_resolution_clock::now() - startTime_2;
std::cout << "unordered_map Time: " << chrono::duration_cast<chrono::milliseconds>(elapsedTime_2).count() << " ms" << std::endl;
return 0;
}