ProgramMemory: avoid unnecessary copy in erase_if()#6652
ProgramMemory: avoid unnecessary copy in erase_if()#6652firewave wants to merge 1 commit intocppcheck-opensource:mainfrom
erase_if()#6652Conversation
|
Clang 17 The example from https://trac.cppcheck.net/ticket/10765#comment:4: Clang 17 I thought this improves things slightly. Seems like I misread the local results I had before. But maybe it will improve things if the use count thing is fixed... |
| continue; | ||
|
|
||
| copyOnWrite(); | ||
| mValues->erase(it->first); |
There was a problem hiding this comment.
This requires double iteration for ever element that will be erased.
There was a problem hiding this comment.
Yeah - the code isn't great. I mainly opened this to raise awareness and gather feedback for a better implementation (if even possible).
| it = mValues->erase(it); | ||
| else | ||
| ++it; | ||
| for (auto it = values->begin(); it != values->end(); ++it) { |
There was a problem hiding this comment.
The initial value should come from find_if:
for (auto it = std::find_if(mValues->begin(), mValues->end(), [](const auto& x) { return pred(x.first); }); it != mValues->end(); ++it) {
copyOnWrite();
if (pred(it->first))
it = mValues->erase(it);
else
++it;
}There was a problem hiding this comment.
You can move the copyOnWrite out of the loop by doing find_if outside of the for statement:
auto it = std::find_if(mValues->begin(), mValues->end(), [](const auto& x) { return pred(x.first); });
if (it == mValues->end())
return;
copyOnWrite();
for (; it != values->end(); ++it) {
if (pred(it->first))
it = mValues->erase(it);
else
++it;
}There was a problem hiding this comment.
The container behind mValues changes which renders the iterators invalid.
| else | ||
| ++it; | ||
| } | ||
| } |
There was a problem hiding this comment.
I dont think this extra branch is needed. Especially if you can move the copyOnWrite out of the loop.
|
The latest rework get rid of the unnecessary copy-on-writes and tries to minimizes the redundant work. Unfortunately this is not really faster at all with few conditions - needs some more looking at with more complex code though. It exposed an issue with |
auto it = std::find_if(mValues->cbegin(), mValues->cend(), [&pred](const decltype(mValues->cbegin())::value_type& entry) {
return pred(entry.first);
});The actual type provided by this is |
I filed an upstream ticket about detecting this: llvm/llvm-project#104572. Still need to file one about detecting it ourselves. |
5db44a9 to
47dc554
Compare
|
This greatly reduces the amount of copies but in the used test cases it does not translate into any visible improvements. Let's see what the selfcheck says. |
No description provided.