From 4fce2aa381000d24f8e2c89282a8fbbb172c43c2 Mon Sep 17 00:00:00 2001 From: LadyCailin Date: Fri, 5 Apr 2019 10:56:38 +0200 Subject: [PATCH] Add some caches to speed things up in the course of operation --- .../PureUtilities/Common/ClassUtils.java | 10 +++++++++- .../laytonsmith/core/constructs/CClassType.java | 2 +- .../core/constructs/NativeTypeList.java | 16 +++++++++++++--- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/laytonsmith/PureUtilities/Common/ClassUtils.java b/src/main/java/com/laytonsmith/PureUtilities/Common/ClassUtils.java index 699ba3212..43710492e 100644 --- a/src/main/java/com/laytonsmith/PureUtilities/Common/ClassUtils.java +++ b/src/main/java/com/laytonsmith/PureUtilities/Common/ClassUtils.java @@ -1,8 +1,10 @@ package com.laytonsmith.PureUtilities.Common; import java.util.HashSet; +import java.util.Map; import java.util.Objects; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -43,6 +45,7 @@ public static Class forCanonicalName(String className, boolean initialize, Class return forCanonicalName(className, true, initialize, classLoader); } + private static final Map CANONICAL_CLASS_CACHE = new ConcurrentHashMap<>(); /** * Private version, which accepts the useInitializer parameter. * @@ -53,7 +56,11 @@ public static Class forCanonicalName(String className, boolean initialize, Class * @return * @throws ClassNotFoundException */ - private static Class forCanonicalName(String className, boolean useInitializer, boolean initialize, ClassLoader classLoader) throws ClassNotFoundException { + private static Class forCanonicalName(String className, boolean useInitializer, boolean initialize, + ClassLoader classLoader) throws ClassNotFoundException { + if(CANONICAL_CLASS_CACHE.containsKey(className)) { + return CANONICAL_CLASS_CACHE.get(className); + } if("void".equals(className)) { return void.class; } @@ -144,6 +151,7 @@ private static Class forCanonicalName(String className, boolean useInitializer, throw ex; } } + CANONICAL_CLASS_CACHE.put(className, c); return c; } diff --git a/src/main/java/com/laytonsmith/core/constructs/CClassType.java b/src/main/java/com/laytonsmith/core/constructs/CClassType.java index 712859b13..da3a5eee0 100644 --- a/src/main/java/com/laytonsmith/core/constructs/CClassType.java +++ b/src/main/java/com/laytonsmith/core/constructs/CClassType.java @@ -262,7 +262,6 @@ private void instantiateInvalidType(Environment env) { } else if("ms.lang.ClassType".equals(fqcn)) { invalidType = new Mixed[]{this}; } else { - ObjectDefinitionTable odt = env.getEnv(CompilerEnvironment.class).getObjectDefinitionTable(); invalidType = new Mixed[types.size()]; for(int i = 0; i < invalidType.length; i++) { // TODO: For now, we must use this mechanism, since we don't populate the ODT with @@ -270,6 +269,7 @@ private void instantiateInvalidType(Environment env) { if(NativeTypeList.getNativeTypeList().contains(this.fqcn)) { invalidType[i] = NativeTypeList.getInvalidInstanceForUse(this.fqcn); } else { + ObjectDefinitionTable odt = env.getEnv(CompilerEnvironment.class).getObjectDefinitionTable(); ObjectDefinition od = odt.get(this.fqcn); invalidType[i] = new UserObject(Target.UNKNOWN, null, env, od, null); } diff --git a/src/main/java/com/laytonsmith/core/constructs/NativeTypeList.java b/src/main/java/com/laytonsmith/core/constructs/NativeTypeList.java index 6dc258b57..ea19c2a6d 100644 --- a/src/main/java/com/laytonsmith/core/constructs/NativeTypeList.java +++ b/src/main/java/com/laytonsmith/core/constructs/NativeTypeList.java @@ -41,6 +41,8 @@ public class NativeTypeList { */ public static final String INVALID_INSTANCE_METHOD_NAME = "ConstructInvalidInstance"; + private static final Map INVALID_INSTANCE_CACHE = new ConcurrentHashMap<>(); + /** * Given a simple name of a class, attempts to resolve * within the native types (not user defined types). If the class can't be found, null is returned, @@ -288,15 +290,23 @@ public static Class getInterfaceRunnerFor(FullyQ * @throws java.lang.ClassNotFoundException */ public static Mixed getInvalidInstanceForUse(FullyQualifiedClassName fqcn) throws ClassNotFoundException { + if(INVALID_INSTANCE_CACHE.containsKey(fqcn)) { + return INVALID_INSTANCE_CACHE.get(fqcn); + } Class c = getNativeClassOrInterfaceRunner(fqcn); if(ReflectionUtils.hasMethod(c, INVALID_INSTANCE_METHOD_NAME, Mixed.class)) { - return (Mixed) ReflectionUtils.invokeMethod(c, null, INVALID_INSTANCE_METHOD_NAME); + Mixed m = (Mixed) ReflectionUtils.invokeMethod(c, null, INVALID_INSTANCE_METHOD_NAME); + INVALID_INSTANCE_CACHE.put(fqcn, m); + return m; } + Mixed m; if(MEnumType.class.isAssignableFrom(c)) { - return getNativeEnumType(fqcn); + m = getNativeEnumType(fqcn); } else { // Not abstract - return ReflectionUtils.instantiateUnsafe(c); + m = ReflectionUtils.instantiateUnsafe(c); } + INVALID_INSTANCE_CACHE.put(fqcn, m); + return m; } /**