Permalink
Browse files

Massively speed up reflect_pull() for enums.

This avoids loading classes that we don't need to load, since we only need to do that to get the ENUM values for the one class. This also improves getting ENUM inner classes. Previously when getting the class's common name it would change "$" to "." for inner classes. However, the only case where this method is used it needs to the "$" to find the class. So it throws an exception, we catch it, add the "$" back and try again. This is very expensive and seeminlgy not needed. Finally, I removed a redundant HashSet creation that used about 25% of the remaining time. Overall this went from freezing the server for a few seconds to completing in less than a millisecond.
  • Loading branch information...
PseudoKnight committed Nov 3, 2017
1 parent 7015e9d commit bc5913e24a576508fda3287a5f8727c17bf39fa6
@@ -706,7 +706,7 @@ private ClassMirror getClassMirrorFromJVMName(String className) {
*/
public Set<ClassMirror<?>> getClassesWithAnnotation(Class<? extends Annotation> annotation) {
if (classAnnotationCache.containsKey(annotation)) {
return new HashSet<>(classAnnotationCache.get(annotation));
return classAnnotationCache.get(annotation);
}
doDiscovery();
Set<ClassMirror<?>> mirrors = new HashSet<>();
@@ -193,7 +193,7 @@ public static String getCommonName(Class c){
//This is fine for non arrays.
return c.getName();
}
int arrayCount = c.getName().lastIndexOf("[") + 1;
int arrayCount = c.getName().lastIndexOf('[') + 1;
Class cc = c.getComponentType();
while(cc.isArray()){
cc = cc.getComponentType();
@@ -209,7 +209,7 @@ public static String getCommonName(Class c){
* @return
*/
public static String getCommonNameFromJVMName(String classname){
int arrayCount = classname.lastIndexOf("[") + 1;
int arrayCount = classname.lastIndexOf('[') + 1;
classname = classname.substring(arrayCount);
//ZBSIJDFC
if("Z".equals(classname)){
@@ -231,7 +231,7 @@ public static String getCommonNameFromJVMName(String classname){
} else if("V".equals(classname)){
return "void"; //special case
} else {
classname = classname.substring(1, classname.length() - 1).replace('/', '.').replace('$', '.');
classname = classname.substring(1, classname.length() - 1).replace('/', '.');
}
return classname + StringUtils.stringMultiply(arrayCount, "[]");
}
@@ -1,6 +1,7 @@
package com.laytonsmith.core.functions;
import com.laytonsmith.PureUtilities.ClassLoading.ClassDiscovery;
import com.laytonsmith.PureUtilities.ClassLoading.ClassMirror.ClassMirror;
import com.laytonsmith.PureUtilities.ClassLoading.DynamicEnum;
import com.laytonsmith.PureUtilities.Common.ReflectionUtils;
import com.laytonsmith.PureUtilities.Version;
@@ -163,29 +164,29 @@ public Construct exec(Target t, Environment env, Construct... args) throws Confi
return new CArray(t, protocols);
} else if("enum".equalsIgnoreCase(param)){
CArray a = new CArray(t);
Set<Class<Enum>> enums = ClassDiscovery.getDefaultInstance().loadClassesWithAnnotationThatExtend(MEnum.class, Enum.class);
Set<Class<DynamicEnum>> dEnums = ClassDiscovery.getDefaultInstance().loadClassesWithAnnotationThatExtend(MDynamicEnum.class, DynamicEnum.class);
Set<ClassMirror<Enum>> enums = ClassDiscovery.getDefaultInstance().getClassesWithAnnotationThatExtend(MEnum.class, Enum.class);
Set<ClassMirror<DynamicEnum>> dEnums = ClassDiscovery.getDefaultInstance().getClassesWithAnnotationThatExtend(MDynamicEnum.class, DynamicEnum.class);
if(args.length == 1){
//No name provided
for(Class<Enum> e : enums){
a.push(new CString(e.getAnnotation(MEnum.class).value(), t), t);
for(ClassMirror<Enum> e : enums){
a.push(new CString((String) e.getAnnotation(MEnum.class).getValue("value"), t), t);
}
for (Class<DynamicEnum> d : dEnums) {
a.push(new CString(d.getAnnotation(MDynamicEnum.class).value(), t), t);
for (ClassMirror<DynamicEnum> d : dEnums) {
a.push(new CString((String) d.getAnnotation(MDynamicEnum.class).getValue("value"), t), t);
}
} else if(args.length == 2){
String enumName = args[1].val();
for(Class<Enum> e : enums){
if(e.getAnnotation(MEnum.class).value().equals(enumName)){
for(Enum ee : e.getEnumConstants()){
for(ClassMirror<Enum> e : enums){
if(e.getAnnotation(MEnum.class).getValue("value").equals(enumName)){
for(Enum ee : e.loadClass().getEnumConstants()){
a.push(new CString(ee.name(), t), t);
}
break;
}
}
for (Class<DynamicEnum> d : dEnums) {
if (d.getAnnotation(MDynamicEnum.class).value().equals(enumName)) {
for (DynamicEnum ee : (Collection<DynamicEnum>) ReflectionUtils.invokeMethod(d, null, "values")) {
for (ClassMirror<DynamicEnum> d : dEnums) {
if (d.getAnnotation(MDynamicEnum.class).getValue("value").equals(enumName)) {
for (DynamicEnum ee : (Collection<DynamicEnum>) ReflectionUtils.invokeMethod(d.loadClass(), null, "values")) {
a.push(new CString(ee.name(), t), t);
}
break;

0 comments on commit bc5913e

Please sign in to comment.