Bug 234898 [expressions] Expressions.isSubtype is very expensive
diff --git a/bundles/org.eclipse.core.expressions/src/org/eclipse/core/internal/expressions/Expressions.java b/bundles/org.eclipse.core.expressions/src/org/eclipse/core/internal/expressions/Expressions.java
index 8c39ed7..50981d6 100644
--- a/bundles/org.eclipse.core.expressions/src/org/eclipse/core/internal/expressions/Expressions.java
+++ b/bundles/org.eclipse.core.expressions/src/org/eclipse/core/internal/expressions/Expressions.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -12,7 +12,9 @@
import java.util.ArrayList;
import java.util.Collection;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import org.w3c.dom.Element;
@@ -26,6 +28,11 @@
import org.eclipse.core.expressions.IIterable;
public class Expressions {
+
+ /**
+ * Cache to optimize instanceof computation. Map of String->Map(String, Boolean).
+ */
+ private static final Map knownClasses = new HashMap();
/* debugging flag to enable tracing */
public static final boolean TRACING;
@@ -45,15 +52,32 @@
return isSubtype(element.getClass(), type);
}
- private static boolean isSubtype(Class clazz, String type) {
+ private static synchronized boolean isSubtype(Class clazz, String type) {
+ String clazzName = clazz.getName();
+ Map nameMap = (Map) knownClasses.get(clazzName);
+ if (nameMap != null) {
+ Object obj = nameMap.get(type);
+ if (obj != null)
+ return ((Boolean)obj).booleanValue();
+ }
+ if (nameMap == null) {
+ nameMap = new HashMap();
+ knownClasses.put(clazzName, nameMap);
+ }
+ boolean isSubtype = uncachedIsSubtype(clazz, type);
+ nameMap.put(type, isSubtype ? Boolean.TRUE : Boolean.FALSE);
+ return isSubtype;
+ }
+
+ private static boolean uncachedIsSubtype(Class clazz, String type) {
if (clazz.getName().equals(type))
return true;
Class superClass= clazz.getSuperclass();
- if (superClass != null && isSubtype(superClass, type))
+ if (superClass != null && uncachedIsSubtype(superClass, type))
return true;
Class[] interfaces= clazz.getInterfaces();
for (int i= 0; i < interfaces.length; i++) {
- if (isSubtype(interfaces[i], type))
+ if (uncachedIsSubtype(interfaces[i], type))
return true;
}
return false;