New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use map::find rather than insert to avoid creating temporary #13884
Conversation
I have a hard time seeing how this is better. If you call I think if you wanted to address some cost, you should use (If I understand the code right, you actually want an "insert or overwrite" semantic. |
I understand your point, and indeed was the premise why we wrote the code like this originally. The problem is, at least for GNU STL implementation that I have on my machine (and that is also used by my clang), that #include <map>
#include <iostream>
__attribute__((noinline))
void compute(std::map<unsigned int, unsigned int> &v1, unsigned int element)
{
auto it = v1.insert(std::make_pair(element, 2 * element));
if (it.second == false)
it.first->second *= 3;
}
__attribute__((noinline))
void compute2(std::map<unsigned int, unsigned int> &v1, unsigned int element)
{
auto it = v1.find(element);
if (it != v1.end())
it->second *= 3;
else
v1.insert(std::make_pair(element, 2 * element));
}
int main()
{
std::map<unsigned int, unsigned int> map;
compute2(map, 2);
compute2(map, 3);
for (unsigned int i=0; i<10; ++i)
compute2(map, 2);
compute2(map, 4);
for (unsigned int i=0; i<4; ++i)
compute2(map, 4);
for (const auto it : map)
std::cout << it.first << " " << it.second << std::endl;
return 0;
} If you run the code like this, you should get 3 calls to |
Unfortunately not, I rather need the semantic "insert or look up", which I use to detect duplicates in a list that later gets saved in a vector, so the key is the element I want to find similarities of, and the value in the map is the first such index that I can use to match the list of values with the position in the vector. |
Ah, I see now. The key is the 99% hit rate. Thanks for the explanation, let's get this merged then. |
Oh, oops. I just violated the rule spelled out just a few minutes ago: Anything that isn't tagged 9.4 should wait. Should I revert? |
No, this should be rather safe (and if it is breaking tests, we can revert then.) I will keep an eye on the testers. |
For reference, the benchmark |
Nice! |
Use map::find rather than insert to avoid creating temporary
When looking at our performance tests I realized we create unnecessary temporaries when checking for the presence of an element in a map. It is better to use
map::find()
first and only insert when the search was unsuccessful.This is a small performance improvement but not important for the 9.4 release.