eranif / codelite

A multi purpose IDE specialized in C/C++/Rust/Python/PHP and Node.js. Written in C++
https://codelite.org
GNU General Public License v2.0
2.09k stars 448 forks source link

[Bug]: Codelite hand during rebuild project #3298

Closed rozhuk-im closed 4 months ago

rozhuk-im commented 5 months ago

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 on ZombieReaperPOSIX::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

git clone https://github.com/rozhuk-im/gtk-mixer.git
Open workspace in Codelite
Try to REBUILD debug configuration

Relevant log output

No response

rozhuk-im commented 5 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];
eranif commented 5 months ago

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)

rozhuk-im commented 5 months ago

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.

eranif commented 5 months ago

.... // 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);
        }
    }
rozhuk-im commented 5 months ago

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.

eranif commented 5 months ago

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