Class.getGenericInterfaces performance improvement (original) (raw)
Doug Lea dl at cs.oswego.edu
Sat Jun 8 15:07:00 UTC 2013
- Previous message: hg: jdk8/tl/jdk: 7124706: enable RetransformBigClass.sh test when fix for 8013063 is promoted
- Next message: Proposal: Comparables.isCommutativelyComparable
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
While tracking down performance issues in some reflective checks used inside ConcurrentHashMap, I noticed that method Class.getGenericInterfaces (as well as methods getGenericSuperclass and getTypeParameters) entail an expensive unnecessary recheck on each invocation.
Each relies primarily on (internal) method getGenericInfo, that uses an instance cached on first invocation (or remains null if the class is not generic). But these calling methods preface the call with a call to getGenericSignature which is a relatively expensive JNI method. This call is unnecessary if the genericInfo has already been constructed. Reworking to avoid this makes repeated calls very noticeably faster.
The diffs below show one way to do this. Could someone who works on reflection check and sponsor this change?
Thanks!
diff -r 30101f69e66f src/share/classes/java/lang/Class.java --- a/src/share/classes/java/lang/Class.java Fri May 17 10:11:35 2013 -0700 +++ b/src/share/classes/java/lang/Class.java Sat Jun 08 10:33:32 2013 -0400 @@ -707,8 +707,9 @@ */ @SuppressWarnings("unchecked") public TypeVariable<Class>[] getTypeParameters() {
if (getGenericSignature() != null)
return (TypeVariable<Class<T>>[])getGenericInfo().getTypeParameters();
ClassRepository info = getGenericInfo();
if (info != null)
return (TypeVariable<Class<T>>[])info.getTypeParameters(); else return (TypeVariable<Class<T>>[])new TypeVariable<?>[0]; }
@@ -758,15 +759,13 @@ * @since 1.5 */ public Type getGenericSuperclass() {
if (getGenericSignature() != null) {
// Historical irregularity:
// Generic signature marks interfaces with superclass = Object
// but this API returns null for interfaces
if (isInterface())
return null;
return getGenericInfo().getSuperclass();
} else
return getSuperclass();
// Historical irregularity:
// Generic signature marks interfaces with superclass = Object
// but this API returns null for interfaces
ClassRepository info = getGenericInfo();
return (info == null ? getSuperclass() :
isInterface() ? null :
info.getSuperclass()); } /**
@@ -881,10 +880,8 @@ * @since 1.5 */ public Type[] getGenericInterfaces() {
if (getGenericSignature() != null)
return getGenericInfo().getSuperInterfaces();
else
return getInterfaces();
ClassRepository info = getGenericInfo();
return (info == null) ? getInterfaces() : info.getSuperInterfaces(); }
@@ -2409,12 +2406,11 @@ // accessor for generic info repository private ClassRepository getGenericInfo() { // lazily initialize repository if necessary
if (genericInfo == null) {
// create and cache generic info repository
genericInfo = ClassRepository.make(getGenericSignature(),
getFactory());
}
return genericInfo; //return cached repository
String signature;
ClassRepository info = genericInfo;
return (info != null ? info :
(signature = getGenericSignature()) == null ? null :
(genericInfo = ClassRepository.make(signature, getFactory()))); } // Annotations handling
- Previous message: hg: jdk8/tl/jdk: 7124706: enable RetransformBigClass.sh test when fix for 8013063 is promoted
- Next message: Proposal: Comparables.isCommutativelyComparable
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]