From 5fb76fb0ccd5819290dcc465670233ed14b4b1e8 Mon Sep 17 00:00:00 2001 From: "Denis.Zhdanov" Date: Wed, 16 May 2012 11:44:48 +0400 Subject: [PATCH] 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; --- .../src/com/intellij/util/DocumentUtil.java | 54 +++++++++++++++++++ .../codeInsight/daemon/impl/IndentsPass.java | 20 ++++--- .../openapi/editor/impl/EditorImpl.java | 6 ++- 3 files changed, 73 insertions(+), 7 deletions(-) create mode 100644 platform/core-impl/src/com/intellij/util/DocumentUtil.java diff --git a/platform/core-impl/src/com/intellij/util/DocumentUtil.java b/platform/core-impl/src/com/intellij/util/DocumentUtil.java new file mode 100644 index 000000000000..d24da8a3caef --- /dev/null +++ b/platform/core-impl/src/com/intellij/util/DocumentUtil.java @@ -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); + } + } +} diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/IndentsPass.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/IndentsPass.java index fe17d35ddd9f..5ecaffe59ff1 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/IndentsPass.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/IndentsPass.java @@ -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 oldHighlighters = myEditor.getUserData(INDENT_HIGHLIGHTERS_IN_EDITOR_KEY); - List newHighlighters = new ArrayList(); - MarkupModel mm = myEditor.getMarkupModel(); + final List newHighlighters = new ArrayList(); + 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()); 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 533d365499d8..1ed0fe19cd1f 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 @@ -6060,6 +6060,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi List 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++; } }