Closed rozhuk-im closed 4 months ago
Looks like I found why this happen.
Project generate 30+mb log and 500k+ lines of output.
void clRowEntry::InsertChild(clRowEntry* child, clRowEntry* prev)
....
// Connect the linked list for sequential iteration
clRowEntry::Vec_t::iterator iterCur =
std::find_if(m_children.begin(), m_children.end(), [&](clRowEntry* c) { return c == child; });
....
This become very slow after 100k items.
Also lines.erase(lines.begin());
looks slow and can be replaced with:
auto lines = ::wxStringTokenize(m_buffer, "\n", wxTOKEN_RET_DELIMS);
wxString remainder;
//while(!lines.empty()) {
const size_t cnt = lines.Count();
for (size_t i = 0; i < cnt; i ++) {
auto& line = lines[i];
Thanks, looking forward to apply your PR. I posted 2 comments on it (the first comment is crucial, the second is more of a "nit" comment)
https://github.com/eranif/codelite/pull/3304 and https://github.com/eranif/codelite/pull/3305 also here.
Current limit with 8192 lines mostly unreachable, now limiting callm_view->Commit();
and m_view->ScrollToBottom();
save more CPU time than limiting for lines parse.
.... // Connect the linked list for sequential iteration clRowEntry::Vec_t::iterator iterCur = std::find_if(m_children.begin(), m_children.end(), [&](clRowEntry* c) { return c == child; }); ....
This looks redundant. We could use the previous insert and capture the iterator
So the code above this snippet looks like:
// We need the last item of this subtree (prev 'this' is the root)
clRowEntry::Vec_t::iterator iterCur = {};
if(prev == nullptr || prev == this) {
// make it the first item
iterCur = m_children.insert(m_children.begin(), child);
} else {
// optimization:
// we often get here by calling AddChild(), so don't loop over the list, check if `prev`
// is the last item
if(!m_children.empty() && m_children.back() == prev) {
iterCur = m_children.insert(m_children.end(), child);
} else {
// Insert the item in the parent children list
clRowEntry::Vec_t::iterator iter = m_children.end();
iter = std::find_if(m_children.begin(), m_children.end(), [&](clRowEntry* c) { return c == prev; });
if(iter != m_children.end()) {
++iter;
}
// if iter is end(), than the is actually appending the item
iterCur = m_children.insert(iter, child);
}
}
What happen with changes from https://github.com/eranif/codelite/commit/0f46067e547ab5d8461ab2dc101afd1c811adbec ?
My second attempt was to remove all Vec_t crap and leave only double linked list. I am almost done this, but getters that returns m_children confuse me and I revert back to code from PR. Later I think that getter can be implemented by create+fill Vec_t from list.
I really does not understand design: why Vec_t used with double linked list: they do almost same things. Double linked list can be implemented by TAILQ_INIT() staff, that available at least on FreeBSD and linux.
I merged your changes. After I committed my small fix, I noticed that you did the same in the PR, so I resolved the conflict and merged (from GitHub UI)
https://github.com/eranif/codelite/commit/eba94a89ca65e872cfd8964552c1691d9b099be8
What happened?
Codelite infinite call
BuildTab::OnBuildAddLine
have no idea why: I try to debug this but not found who post events, probably it try to process same event infinite times. If it rely onZombieReaperPOSIX::Entry()
- this can be reason, because this code may lost events IMHO.OS: FreeBSD 14/stable
Version
Self compiled
Operating system
Other
Steps to reproduce
Relevant log output
No response