United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: 5058132 (enum) poor performance in compiler-generated Enum.valueOf(String)
5058132 : (enum) poor performance in compiler-generated Enum.valueOf(String)

Details
Type:
Bug
Submit Date:
2004-06-06
Status:
Closed
Updated Date:
2006-10-23
Project Name:
JDK
Resolved Date:
2004-11-06
Component:
tools
OS:
solaris_8,windows_xp
Sub-Component:
javac
CPU:
x86,generic
Priority:
P4
Resolution:
Fixed
Affected Versions:
5.0
Fixed Versions:
6

Related Reports
Duplicate:

Sub Tasks

Description
The compiler-generated code for the static method valueOf(String) in every enum
type scans the list of enumeration constants linearly.  Correct but not very
efficient.  Better would be to delegate to Enum.valueOf(Class,String), which
uses a Map maintained in the class object.

                                    

Comments
CONVERTED DATA

BugTraq+ Release Management Values

COMMIT TO FIX:
dragon
mustang


                                     
2004-09-11
SUGGESTED FIX

--- /tmp/geta9993	2004-09-10 01:46:12.351894400 -0700
+++ Lower.java	2004-09-10 01:15:57.706762392 -0700
@@ -2090,42 +2090,33 @@
 	enumDefs.append(valuesDef);
 
 	// public static E valueOf(String name) {
-	//     for (E #e : VALUES)
-	//         if (#e.name().equals(name))
-	//             return #e;
-	//     throw new IllegalArgumentException(name);
+	//     return Enum.valueOf(ValueOf.class, name);
 	// }
-	Symbol valueOfSym = lookupMethod(tree.pos,
+	MethodSymbol valueOfSym = lookupMethod(tree.pos,
 					 names.valueOf,
 					 tree.sym.type,
 					 Type.emptyList.prepend(syms.stringType));
 	assert (valueOfSym.flags() & STATIC) != 0;
-	VarSymbol nameArgSym = ((MethodSymbol)valueOfSym).params.head;
+	VarSymbol nameArgSym = valueOfSym.params.head;
 	Ident nameVal = (Ident)make.Ident(nameArgSym);
-	VarSymbol eSym = new VarSymbol(SYNTHETIC|FINAL,
-				       names.fromString(target.syntheticNameChar() + "E"),
-				       tree.type,
-				       valueOfSym);
-	Tree returnE = make.Return(make.Ident(eSym));
-	Tree eName = makeCall(make.Ident(eSym), names._name, Tree.emptyList);
-	Tree condition = makeCall(eName, names.fromString("equals"), Tree.emptyList.prepend(nameVal));
-	Tree ifStmt = make.If(condition, returnE, null);
-	Tree foreachLoop = make.ForeachLoop(make.VarDef(eSym, null), make.Ident(valuesVar), ifStmt);
-	NewClass newclass = make.NewClass(null,
-				      null,
-				      make.Ident(syms.illegalArgumentExceptionType.tsym),
-				      Tree.emptyList.prepend(nameVal),
-				      null);
-	newclass.type = syms.illegalArgumentExceptionType;
-	newclass.constructor = lookupMethod(tree.pos,
-					    names.init,
-					    syms.illegalArgumentExceptionType,
-					    Type.emptyList.prepend(syms.stringType));
-	Tree throwStatement = make.Throw(newclass);
+	Tree thisEnum_class = classOfType(tree.type, tree.pos).
+	    setType(new ClassType
+		    (syms.classType.outer(),
+		     Type.emptyList.prepend(types.erasure(tree.type)),
+		     syms.classType.tsym));
+	List<Type> enumValueOfArgTypes = Type.emptyList.
+	    prepend(syms.stringType).
+	    prepend(thisEnum_class.type);
+	Tree enumValueOf =
+	    make.Return(make.TypeCast(tree.type,
+				      makeCall(make.Ident(syms.enumSym),
+					       names.valueOf,
+					       Tree.emptyList.
+					       prepend(nameVal).
+					       prepend(thisEnum_class))));
 	MethodDef valueOf = make.MethodDef((MethodSymbol)valueOfSym,
 					   make.Block(0, Tree.emptyList.
-						      prepend(throwStatement).
-						      prepend(foreachLoop)));
+						      prepend(enumValueOf)));
 	nameVal.sym = valueOf.params.head.sym;
 	enumDefs.append(valueOf);
 
###@###.### 2004-09-10
                                     
2004-09-10
EVALUATION

Will do.

###@###.### 2004-06-06
                                     
2004-06-06



Hardware and Software, Engineered to Work Together