optimisation: merge same tokens to minimize number of highlighters to update

This commit is contained in:
Alexey Kudravtsev
2017-02-13 14:36:48 +03:00
parent 80357763e6
commit 8f6b3dcca8
2 changed files with 18 additions and 7 deletions
@@ -698,18 +698,25 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo
// add token information as range markers
// start from the end because portion of the text can be stripped from the document beginning because of a cycle buffer
int offset = document.getTextLength();
int tokenLength = 0;
for (int i = deferredTokens.size() - 1; i >= startIndex; i--) {
TokenBuffer.TokenInfo token = deferredTokens.get(i);
contentTypes.add(token.contentType);
int tokenLength = token.length();
final HyperlinkInfo info = token.getHyperlinkInfo();
tokenLength += token.length();
TokenBuffer.TokenInfo prevToken = i == startIndex ? null : deferredTokens.get(i - 1);
if (prevToken != null && token.contentType == prevToken.contentType && token.getHyperlinkInfo() == prevToken.getHyperlinkInfo()) {
// do not create highlighter yet because can merge previous token with the current
continue;
}
int start = Math.max(0, offset - tokenLength);
if (start == offset) break;
final HyperlinkInfo info = token.getHyperlinkInfo();
if (info != null) {
myHyperlinks.createHyperlink(start, offset, null, info).putUserData(MANUAL_HYPERLINK, true);
}
createTokenRangeHighlighter(token.contentType, start, offset);
offset = start;
tokenLength = 0;
}
}
finally {
@@ -30,8 +30,12 @@ import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.actionSystem.EditorActionManager;
import com.intellij.openapi.editor.actionSystem.TypedAction;
import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.editor.impl.DocumentMarkupModel;
import com.intellij.openapi.editor.markup.MarkupModel;
import com.intellij.openapi.editor.markup.RangeHighlighter;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.testFramework.*;
import com.intellij.util.Alarm;
@@ -231,20 +235,20 @@ public class ConsoleViewImplTest extends LightPlatformTestCase {
}).cpuBound().assertTiming());
}
/*
public void testPerformanceOfMergeableTokens() throws Exception {
withCycleConsole(1000, console ->
PlatformTestUtil.startPerformanceTest("console print", 1500, () -> {
PlatformTestUtil.startPerformanceTest("console print", 5500, () -> {
console.clear();
for (int i=0; i<10_000_000; i++) {
console.print("xxx\n", ConsoleViewContentType.NORMAL_OUTPUT);
UIUtil.dispatchAllInvocationEvents();
}
LightPlatformCodeInsightTestCase.type('\n', console.getEditor(), getProject());
UIUtil.dispatchAllInvocationEvents();
console.waitAllRequests();
MarkupModel model = DocumentMarkupModel.forDocument(console.getEditor().getDocument(), getProject(), true);
RangeHighlighter highlighter = assertOneElement(model.getAllHighlighters());
assertEquals(new TextRange(0, console.getEditor().getDocument().getTextLength()), TextRange.create(highlighter));
}).cpuBound().assertTiming());
}
*/
private static void withCycleConsole(int capacityKB, Consumer<ConsoleViewImpl> runnable) {
boolean oldUse = UISettings.getInstance().OVERRIDE_CONSOLE_CYCLE_BUFFER_SIZE;