optimization in getTabbedTextWidth calculation to cache last two values calculated: 2-10 speed up due to often caret / scroll position calculation (IDEA-105872)

This commit is contained in:
Maxim.Mossienko
2013-04-22 18:38:38 +02:00
parent b9265da381
commit 5a1f2750b6
@@ -69,6 +69,8 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.openapi.wm.IdeGlassPane;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
import com.intellij.ui.GuiUtils;
import com.intellij.ui.JBColor;
import com.intellij.ui.LightweightHint;
@@ -642,6 +644,8 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
myDescent = -1;
myPlainFontMetrics = null;
clearTextWidthCache();
boolean softWrapsUsedBefore = mySoftWrapModel.isSoftWrappingEnabled();
mySettings.reinitSettings();
@@ -1416,12 +1420,32 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
return result + columnsToProcess;
}
// TODO: tabbed text width is additive, it should be possible to have buckets, containing arguments / values to start with
private final int[] myLastStartOffsets = new int[2];
private final int[] myLastTargetColumns = new int[myLastStartOffsets.length];
private final int[] myLastXs = new int[myLastStartOffsets.length];
private int myLastPosition;
private int hits, totals;
private int getTabbedTextWidth(int startOffset, int targetColumn, int xOffset) {
int x = xOffset;
if (startOffset == 0 && myPrefixText != null) {
x += myPrefixWidthInPixels;
}
if (targetColumn <= 0) return x;
++totals;
for(int i = 0; i < myLastStartOffsets.length; ++i) {
if (startOffset == myLastStartOffsets[i] && targetColumn == myLastTargetColumns[i]) {
++hits;
if ((hits & 0xFF) == 0) {
PsiFile file = PsiDocumentManager.getInstance(myProject).getCachedPsiFile(myDocument);
LOG.info("Hits:" + hits + "," + totals + "," + (file != null ? file.getViewProvider().getVirtualFile():null));
}
return myLastXs[i] + xOffset;
}
}
int offset = startOffset;
CharSequence text = myDocument.getCharsNoThreadCheck();
int textLength = myDocument.getTextLength();
@@ -1492,6 +1516,11 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
x += EditorUtil.getSpaceWidth(fontType, this) * (targetColumn - column);
}
myLastTargetColumns[myLastPosition] = targetColumn;
myLastStartOffsets[myLastPosition] = startOffset;
myLastXs[myLastPosition] = x - xOffset;
myLastPosition = (myLastPosition + 1) % myLastStartOffsets.length;
return x;
}
finally {
@@ -1499,6 +1528,14 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
}
}
private void clearTextWidthCache() {
for(int i = 0; i < myLastStartOffsets.length; ++i) {
myLastTargetColumns[i] = -1;
myLastStartOffsets[i] = - 1;
myLastXs[i] = -1;
}
}
public int visibleLineToY(int line) {
if (line < 0) throw new IndexOutOfBoundsException("Wrong line: " + line);
return line * getLineHeight();
@@ -1601,6 +1638,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
private void changedUpdate(DocumentEvent e) {
if (myScrollPane == null || myDocument.isInBulkUpdate()) return;
clearTextWidthCache();
stopOptimizedScrolling();
mySelectionModel.removeBlockSelection();
@@ -2235,6 +2273,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
// Perform additional activity if soft wrap is added or removed during repainting.
if (mySoftWrapsChanged) {
mySoftWrapsChanged = false;
clearTextWidthCache();
validateSize();
// Repaint editor to the bottom in order to ensure that its content is shown correctly after new soft wrap introduction.