From 5a1f2750b656571e9086561eb7df5343c7885e4d Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Mon, 22 Apr 2013 15:44:05 +0200 Subject: [PATCH] optimization in getTabbedTextWidth calculation to cache last two values calculated: 2-10 speed up due to often caret / scroll position calculation (IDEA-105872) --- .../openapi/editor/impl/EditorImpl.java | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java index 3c677b34470a..e175db7c2fd6 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java @@ -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.