I can't understand logic. I have two containers with same element count: vector
and unordered_map
.
I'm using function that checks time complexity of some function and returns value in milliseconds
auto funcComplexity = [](auto&& func, auto&&... params)
{
const auto& start = high_resolution_clock::now();
for (auto i = 0; i < 100; ++i)
{
// function invocation using perfect forwarding
std::forward<decltype(func)>(func)(std::forward<decltype(params)>(params)...);
}
const auto& stop = high_resolution_clock::now();
return duration_cast<duration<double, std::milli>>(stop - start).count();
};
When I erase an element from the middle of vector
, it actually gives me less time than erasing element from unordered_map
void iterateUMap(std::unordered_map<int, Test> map)
{
map.erase(500);
}
void iterateVector(std::vector<Test> vector)
{
std::remove_if(vector.begin(), vector.end(), [](Test& val)
{
return val.mId == 500;
});
}
int main()
{
auto funcComplexity = [](auto&& func, auto&&... params)
{
const auto& start = high_resolution_clock::now();
for (auto i = 0; i < 10000; ++i)
{
// function invocation using perfect forwarding
std::forward<decltype(func)>(func)(std::forward<decltype(params)>(params)...);
}
const auto& stop = high_resolution_clock::now();
return duration_cast<duration<double, std::milli>>(stop - start).count();
};
std::unordered_map<int, Test> uMap;
for(int i = 0; i < 1000; i++)
{
uMap.try_emplace(i, Test(i));
}
std::vector<Test> vector;
vector.reserve(1000);
for (int i = 0; i < 1000; i++)
{
vector.emplace_back(i);
}
cout << funcComplexity(iterateUMap, uMap) << endl;
cout << endl;
cout << funcComplexity(iterateVector, vector) << endl;
return 0;
}
So the output of those two functions:
For vector is: 52.6565 milliseconds
For U_Map is : 6740.64 milliseconds
Why do erasing from u_map is actually slower than erasing from vector? The same thing happening when I just want to get element. For example:
void iterateUMap(std::unordered_map<int, Test> map)
{
map[500].DoSomething();
}
void iterateVector(std::vector<Test> vector)
{
for (auto& value : vector)
{
if(value.mId == 500)
{
value.DoSomething();
break;
}
}
}