Performance optimisation:

*) caching last font and trying to reuse it during editor size recalculation (used to perform a call to the lock-protected font registry for every document symbol)
*) register highlighters in bulk mode if necessary during indents pass processing;
This commit is contained in:
Denis.Zhdanov
2012-05-16 15:21:33 +04:00
parent e7465cf775
commit 5fb76fb0cc
3 changed files with 73 additions and 7 deletions
@@ -0,0 +1,54 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.util;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.ex.DocumentEx;
import org.jetbrains.annotations.NotNull;
/**
* Is intended to hold utility methods to use during {@link Document} processing.
*
* @author Denis Zhdanov
* @since 5/16/12 10:12 AM
*/
public class DocumentUtil {
private DocumentUtil() {
}
// TODO den add doc
public static void executeInBulk(@NotNull Document document, final boolean executeInBulk, @NotNull Runnable task) {
if (!(document instanceof DocumentEx)) {
task.run();
return;
}
DocumentEx documentEx = (DocumentEx)document;
if (executeInBulk == documentEx.isInBulkUpdate()) {
task.run();
return;
}
documentEx.setInBulkUpdate(executeInBulk);
try {
task.run();
}
finally {
documentEx.setInBulkUpdate(!executeInBulk);
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2010 JetBrains s.r.o.
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -41,6 +41,7 @@ import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiFile;
import com.intellij.psi.tree.TokenSet;
import com.intellij.util.DocumentUtil;
import com.intellij.util.containers.IntStack;
import com.intellij.util.text.CharArrayUtil;
import org.jetbrains.annotations.NotNull;
@@ -231,8 +232,8 @@ public class IndentsPass extends TextEditorHighlightingPass implements DumbAware
if (stamp != null && stamp.longValue() == nowStamp()) return;
List<RangeHighlighter> oldHighlighters = myEditor.getUserData(INDENT_HIGHLIGHTERS_IN_EDITOR_KEY);
List<RangeHighlighter> newHighlighters = new ArrayList<RangeHighlighter>();
MarkupModel mm = myEditor.getMarkupModel();
final List<RangeHighlighter> newHighlighters = new ArrayList<RangeHighlighter>();
final MarkupModel mm = myEditor.getMarkupModel();
int curRange = 0;
@@ -264,9 +265,16 @@ public class IndentsPass extends TextEditorHighlightingPass implements DumbAware
}
}
for (; curRange < myRanges.size(); curRange++) {
newHighlighters.add(createHighlighter(mm, myRanges.get(curRange)));
}
final int startRangeIndex = curRange;
DocumentUtil.executeInBulk(myDocument, myRanges.size() > 10000, new Runnable() {
@Override
public void run() {
for (int i = startRangeIndex; i < myRanges.size(); i++) {
newHighlighters.add(createHighlighter(mm, myRanges.get(i)));
}
}
});
myEditor.putUserData(INDENT_HIGHLIGHTERS_IN_EDITOR_KEY, newHighlighters);
myEditor.putUserData(LAST_TIME_INDENTS_BUILT, nowStamp());
@@ -6060,6 +6060,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
List<? extends SoftWrap> softWraps = getSoftWrapModel().getRegisteredSoftWraps();
int softWrapsIndex = -1;
FontInfo lastFontInfo = null;
for (int line = 0; line < lineCount; line++) {
if (myLineWidths.getQuick(line) != -1) continue;
if (line == lineCount - 1) {
@@ -6158,7 +6159,10 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
}
}
else {
x += ComplementaryFontsRegistry.getFontAbleToDisplay(c, fontSize, fontType, fontName).charWidth(c);
if (lastFontInfo == null || !lastFontInfo.canDisplay(c)) {
lastFontInfo = ComplementaryFontsRegistry.getFontAbleToDisplay(c, fontSize, fontType, fontName);
}
x += lastFontInfo.charWidth(c);
offset++;
}
}