Fix bad performance for `addRules` in `DefaultHighlighter` for big containers
ClosedPublic

Authored by sirgienko on Apr 6 2018, 7:40 PM.

Details

Summary

Now, in addRules we call addRule, which emit rulesChanged, that leads to rehighlight all worksheet. This is useless work, because for each rule in rules container we reprocessing all worksheet. (instead better option to emit rulesChanged only one time after container processing). So, when container is big, performance falls quite strongly, for example highlighter of octave backend spends 2-4 seconds for adding new function. So this changes improve emit logic, calling only one event for rules container.

Test Plan
  1. Start octave backend, write octave function, check, that cantor is freezed for few seconds
  2. Apply patch
  3. Check, that octave backend don't freeze after entry with user function.

Diff Detail

Repository
R55 Cantor
Lint
Lint Skipped
Unit
Unit Tests Skipped
sirgienko created this revision.Apr 6 2018, 7:40 PM
Restricted Application added a project: KDE Edu. · View Herald TranscriptApr 6 2018, 7:40 PM
Restricted Application added a subscriber: KDE Edu. · View Herald Transcript
sirgienko requested review of this revision.Apr 6 2018, 7:40 PM
asemke added a comment.Apr 7 2018, 8:35 AM

Can we try to implement this with a boolean paramer m_suppressRuleChangedSignal instead of adding new functions? In addRules() we set m_suppressRuleChangedSignal = true and use in addRule()

if (!m_supressRuleChangedSignal)
     emit rulesChanged();

The code will be more compact and clean with this. Also, this would be similar to the convention we use in LabPlot.

Can you please provide your octave functions which you used to test with?

P.S. : the template for DefaultHighlighter::addRules() in defaulthighlighter.h looks like an overkill - this function is called only twice in the code and the container is always QStringList. The same is true most probably for other templated add*() funcitons in defaulthighlighter.h. We should simplify this maybe.

Can you please provide your octave functions which you used to test with?

#Entry 1
function nothing(n)
  printf("do nothing");
endfunction;
#Entry 2
function nothing1(n)
  printf("do nothing");
endfunction;
#Entry 3
function nothing2(n)
  printf("do nothing");
endfunction;
#Entry 4
function nothing3(n)
  printf("do nothing");
endfunction;
#Entry 5
function nothing4(n)
  printf("do nothing");
endfunction;


Without this patch, it takes 4-5 seconds to run this 5 entries.

P.S. : the template for DefaultHighlighter::addRules() in defaulthighlighter.h looks like an overkill - this function is called only twice in the code and the container is always QStringList. The same is true most probably for other templated add*() funcitons in defaulthighlighter.h. We should simplify this maybe.

I agree, that we should simplify this templates methods to not template functions, which acepting QStringList. Should I add it to this diff?

sirgienko updated this revision to Diff 31575.Apr 7 2018, 9:38 AM

Can we try to implement this with a boolean paramer m_suppressRuleChangedSignal instead of adding new functions? In addRules() we set m_suppressRuleChangedSignal = true and use in addRule()

if (!m_supressRuleChangedSignal)
     emit rulesChanged();

The code will be more compact and clean with this. Also, this would be similar to the convention we use in LabPlot.

Done

Err, something wrong with upload diff: updated diff apply to previous diff?

sirgienko updated this revision to Diff 31576.Apr 7 2018, 9:47 AM

Add correct diff

Can we try to implement this with a boolean paramer m_suppressRuleChangedSignal instead of adding new functions? In addRules() we set m_suppressRuleChangedSignal = true and use in addRule()

if (!m_supressRuleChangedSignal)
     emit rulesChanged();

The code will be more compact and clean with this. Also, this would be similar to the convention we use in LabPlot.

Done

This is not exactly what I meant. bool m_suppressRuleChangeSignal is a private class member (that's why m_ in the name) which is initialized in the constructor to false. We don't need to change the function signatures. We only add

m_suppressRuleChangedSignal = true;
for (;i != end; ++i)
    addRule(*i, format);
m_suppressRuleChangedSignal = false;

in DefaultHighlither::addRules() and that

if (!m_suppressRuleChangedSignal)
    emit ruleChanged();

that you already have now in DefaultHighlighter::addRule(). And similar for removeRule-stuff. No need to change the signatures of the already available functions.

Since we don't have any private members in DefaultHighlighter except of the add pointers, simply add bool suppressRuleChangedSignal to DefaultHighlighterPrivate instead of adding m_suppressRuleChangedSignal to DefaultHighlighter and use it via d->suppressRuleChangedSignal.

I agree, that we should simplify this templates methods to not template functions, which acepting QStringList. Should I add it to this diff?

Yes, please. Let's do the clean-up here in the same diff.

asemke added a comment.Apr 8 2018, 1:59 PM

Your diff seems to be wrong. Looks like you calculated the diff between the current version and the temporary version you had before with m_supressRuleChangedSignal. Can you please upload the corrected diff?

sirgienko updated this revision to Diff 31670.Apr 8 2018, 2:12 PM

@asemke, Is it correct now?

asemke accepted this revision.Apr 8 2018, 3:00 PM
This revision is now accepted and ready to land.Apr 8 2018, 3:00 PM
This revision was automatically updated to reflect the committed changes.