From 5e74a8b399e0f1a67b06d2f6e4989b5c4ef401dc Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Fri, 23 Apr 2010 14:37:32 +0400 Subject: [PATCH] performance optimizations for lookup with many items: - avoid expensive Class#isInstanceOf of LookupElement sublcasses #as using specialized #from with explicit instanceof SpecificLookupItem - using identity hashing for binding lookup item weights to item --- .../completion/CastingLookupElementDecorator.java | 10 ++++++++++ .../completion/JavaChainLookupElement.java | 2 +- .../codeInsight/completion/JavaCompletionUtil.java | 12 +++++++++++- .../completion/JavaSmartCompletionContributor.java | 2 +- .../codeInsight/completion/PreferSimpleWeigher.java | 4 ++-- .../codeInsight/lookup/PsiTypeLookupItem.java | 10 ++++++++++ .../psi/util/proximity/JavaInheritanceWeigher.java | 2 +- .../completion/PrioritizedLookupElement.java | 10 ++++++++-- .../completion/CompletionLookupArranger.java | 3 ++- .../codeInsight/completion/PriorityWeigher.java | 4 ++-- 10 files changed, 48 insertions(+), 11 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/CastingLookupElementDecorator.java b/java/java-impl/src/com/intellij/codeInsight/completion/CastingLookupElementDecorator.java index 5b9b54a039ef..c9e5c70a7bfd 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/CastingLookupElementDecorator.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/CastingLookupElementDecorator.java @@ -78,4 +78,14 @@ public class CastingLookupElementDecorator extends LookupElementDecorator() { public void consume(final LookupElement lookupElement) { - final TypedLookupItem typed = lookupElement.as(TypedLookupItem.class); + final TypedLookupItem typed = JavaCompletionUtil.typedFrom(lookupElement); if (typed != null) { final PsiType psiType = typed.getType(); if (psiType != null && type.isAssignableFrom(psiType)) { diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/PreferSimpleWeigher.java b/java/java-impl/src/com/intellij/codeInsight/completion/PreferSimpleWeigher.java index 1920fffbdf7e..654d58545fe4 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/PreferSimpleWeigher.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/PreferSimpleWeigher.java @@ -25,11 +25,11 @@ import org.jetbrains.annotations.NotNull; public class PreferSimpleWeigher extends CompletionWeigher { public Comparable weigh(@NotNull final LookupElement item, final CompletionLocation location) { - final PsiTypeLookupItem lookupItem = item.as(PsiTypeLookupItem.class); + final PsiTypeLookupItem lookupItem = PsiTypeLookupItem.from(item); if (lookupItem != null) { return -lookupItem.getBracketsCount(); } - if (item.as(CastingLookupElementDecorator.class) != null) { + if (CastingLookupElementDecorator.from(item) != null) { return -239; } return 0; diff --git a/java/java-impl/src/com/intellij/codeInsight/lookup/PsiTypeLookupItem.java b/java/java-impl/src/com/intellij/codeInsight/lookup/PsiTypeLookupItem.java index 687ce14d5c2c..5ad8b86fddc1 100644 --- a/java/java-impl/src/com/intellij/codeInsight/lookup/PsiTypeLookupItem.java +++ b/java/java-impl/src/com/intellij/codeInsight/lookup/PsiTypeLookupItem.java @@ -103,4 +103,14 @@ public class PsiTypeLookupItem extends LookupItem { } return new LookupItem(type, type.getPresentableText()); } + + public static @Nullable PsiTypeLookupItem from(LookupElement element) { + if (element instanceof PsiTypeLookupItem) return (PsiTypeLookupItem)element; + else if (element instanceof LookupElementDecorator) { + element = ((LookupElementDecorator)element).getDelegate(); + if (element instanceof PsiTypeLookupItem) return (PsiTypeLookupItem)element; + } + + return null; + } } diff --git a/java/java-impl/src/com/intellij/psi/util/proximity/JavaInheritanceWeigher.java b/java/java-impl/src/com/intellij/psi/util/proximity/JavaInheritanceWeigher.java index ac39286e7063..38d818e35e97 100644 --- a/java/java-impl/src/com/intellij/psi/util/proximity/JavaInheritanceWeigher.java +++ b/java/java-impl/src/com/intellij/psi/util/proximity/JavaInheritanceWeigher.java @@ -18,8 +18,8 @@ package com.intellij.psi.util.proximity; import com.intellij.psi.*; import com.intellij.psi.util.ProximityLocation; import com.intellij.psi.util.PsiTreeUtil; -import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; /** diff --git a/platform/lang-api/src/com/intellij/codeInsight/completion/PrioritizedLookupElement.java b/platform/lang-api/src/com/intellij/codeInsight/completion/PrioritizedLookupElement.java index 9b6b1a6d03cb..13df562fcc7b 100644 --- a/platform/lang-api/src/com/intellij/codeInsight/completion/PrioritizedLookupElement.java +++ b/platform/lang-api/src/com/intellij/codeInsight/completion/PrioritizedLookupElement.java @@ -18,6 +18,7 @@ package com.intellij.codeInsight.completion; import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.LookupElementDecorator; +import org.jetbrains.annotations.Nullable; /** * Use only when you want to control lookup sorting & preference in simple cases when you have control over ALL the items in lookup. @@ -45,13 +46,18 @@ public class PrioritizedLookupElement extends LookupEle } public static LookupElement withPriority(LookupElement element, double priority) { - final PrioritizedLookupElement prioritized = element.as(PrioritizedLookupElement.class); + final PrioritizedLookupElement prioritized = PrioritizedLookupElement.from(element); return new PrioritizedLookupElement(element, priority, prioritized == null ? 0 : prioritized.getGrouping()); } public static LookupElement withGrouping(LookupElement element, int grouping) { - final PrioritizedLookupElement prioritized = element.as(PrioritizedLookupElement.class); + final PrioritizedLookupElement prioritized = PrioritizedLookupElement.from(element); return new PrioritizedLookupElement(element, prioritized == null ? 0 : prioritized.getPriority(), grouping); } + public static @Nullable PrioritizedLookupElement from(LookupElement element) { + if (element instanceof PrioritizedLookupElement) return (PrioritizedLookupElement)element; + if (element instanceof LookupElementDecorator) return from (((LookupElementDecorator)element).getDelegate()); + return null; + } } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionLookupArranger.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionLookupArranger.java index 65886970728a..9c9068afcb66 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionLookupArranger.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionLookupArranger.java @@ -28,6 +28,7 @@ import com.intellij.psi.WeighingService; import com.intellij.psi.statistics.StatisticsInfo; import com.intellij.psi.statistics.StatisticsManager; import gnu.trove.THashMap; +import gnu.trove.TObjectHashingStrategy; import java.util.Collections; import java.util.Comparator; @@ -40,7 +41,7 @@ public class CompletionLookupArranger extends LookupArranger { static final String IGNORED = "ignored"; private final CompletionLocation myLocation; public static final Key WEIGHT = Key.create("WEIGHT"); - private final Map mySortingWeights = new THashMap(); + private final Map mySortingWeights = new THashMap(TObjectHashingStrategy.IDENTITY); public CompletionLookupArranger(final CompletionParameters parameters) { myLocation = new CompletionLocation(parameters); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/PriorityWeigher.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/PriorityWeigher.java index f50560139306..3483b3962aa0 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/PriorityWeigher.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/PriorityWeigher.java @@ -26,12 +26,12 @@ import com.intellij.codeInsight.lookup.LookupItem; public class PriorityWeigher extends CompletionWeigher { @Override public Double weigh(@NotNull LookupElement element, CompletionLocation location) { - final PrioritizedLookupElement prioritized = element.as(PrioritizedLookupElement.class); + final PrioritizedLookupElement prioritized = PrioritizedLookupElement.from(element); if (prioritized != null) { return -prioritized.getPriority(); } - final LookupItem item = element.as(LookupItem.class); + final LookupItem item = LookupItem.from(element); if (item != null) { return -item.getPriority(); }