diff --git a/platform/core-impl/src/com/intellij/psi/impl/source/tree/LeafElement.java b/platform/core-impl/src/com/intellij/psi/impl/source/tree/LeafElement.java index e33bcb41bf24..0df2c3f08a13 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/source/tree/LeafElement.java +++ b/platform/core-impl/src/com/intellij/psi/impl/source/tree/LeafElement.java @@ -19,9 +19,11 @@ package com.intellij.psi.impl.source.tree; import com.intellij.lang.ASTFactory; import com.intellij.lang.ASTNode; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.Key; import com.intellij.psi.PsiElement; import com.intellij.psi.tree.IElementType; import com.intellij.psi.tree.TokenSet; +import com.intellij.reference.SoftReference; import com.intellij.util.IncorrectOperationException; import com.intellij.util.text.CharArrayUtil; import org.jetbrains.annotations.NotNull; @@ -29,6 +31,7 @@ import org.jetbrains.annotations.Nullable; public abstract class LeafElement extends TreeElement { private static final Logger LOG = Logger.getInstance("com.intellij.psi.impl.source.tree.LeafElement"); + private static final Key> CACHED_TEXT = Key.create("CACHED_TEXT"); private static final int TEXT_MATCHES_THRESHOLD = 5; @@ -58,6 +61,15 @@ public abstract class LeafElement extends TreeElement { @Override public String getText() { + if (myText.length() > 1000 && !(myText instanceof String)) { // e.g. a large text file + String text = SoftReference.dereference(getUserData(CACHED_TEXT)); + if (text == null) { + text = myText.toString(); + putUserData(CACHED_TEXT, new SoftReference(text)); + } + return text; + } + return myText.toString(); } diff --git a/spellchecker/testSrc/com/intellij/spellchecker/inspection/SpellcheckerPerformanceTest.groovy b/spellchecker/testSrc/com/intellij/spellchecker/inspection/SpellcheckerPerformanceTest.groovy new file mode 100644 index 000000000000..96184bf1b6e2 --- /dev/null +++ b/spellchecker/testSrc/com/intellij/spellchecker/inspection/SpellcheckerPerformanceTest.groovy @@ -0,0 +1,32 @@ +/* + * Copyright 2000-2014 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.spellchecker.inspection +import com.intellij.testFramework.PlatformTestUtil +/** + * @author peter + */ +public class SpellcheckerPerformanceTest extends SpellcheckerInspectionTestCase { + + public void "test large text file with many typos"() { + int typoCount = 150000 + String text = "aaaaaaaaa " * typoCount // about 1.5M + myFixture.configureFromExistingVirtualFile(myFixture.addFileToProject("foo.txt", text).virtualFile) + + myFixture.enableInspections(inspectionTools) + PlatformTestUtil.assertTiming("highlighting too long", 5000) { assertSize(typoCount, myFixture.doHighlighting()) } + } + +}