问题
I'm trying to compare this two ways to achieving the enums values (with and without reflection).
So this is my test class:
public class ReflectionOnEnumsTests2 {
enum TestEnum { ONE, TWO, THREE; }
public static void main(String[] args) {
long n = 600_000_000;
int stub;
//test without Reflection
long timeStartWithoutReflection = System.currentTimeMillis();
for (int i = 0; i < n; i++){
TestEnum[] values = TestEnum.values();
stub = values.length;
}
System.out.println("Time consuming with reflection: " + (System.currentTimeMillis() - timeStartWithoutReflection));
//test Reflection
long timeStartWithReflection = System.currentTimeMillis();
for (int i = 0; i < n; i++){
TestEnum[] values = TestEnum.class.getEnumConstants();
stub = values.length;
}
System.out.println("Time consuming with reflection: " + (System.currentTimeMillis() - timeStartWithReflection));
}
}
And I'm confused about the test results. There is approximately the same time consuming. I expected that class.getEnumConstants would be much slower than values() method.
Results:
Time consuming with reflection: 6050
Time consuming with reflection: 7483
JDK version: 1.8.0_60
Question:
So why there is no difference in performance?
回答1:
So why there is no difference in performance?
Your own tests show the non-reflective approach being around 20% faster. That may not be as much as you expected, but it's a non-trivial difference.
In fact, though, it's difficult to generalize your results in any way. Performance-testing Java is tricky. JIT compilation in particular can cause synthetic benchmarks such as yours to produce results that represent only themselves, and do not accurately characterize performance that can be expected in real application contexts.
In any event, you are proposing the wrong criterion for comparing these two approaches. You should use the ordinary, non-reflective approach wherever you can because it provides a better API, even if the performance difference is only moderate. The only reason ever to use reflection is that you cannot know enough until run time to determine the details of the action to take. Such circumstances are rare.
回答2:
I am not surprised at those results.
When java loads an enum
, a list of the values in the Class
object, it will also create methods to access that list (namely values()
).
When you use TestEnum.values();
you will be given this list of values, and when you use TestEnum.class.getEnumConstants();
all you are doing is getting the Class
object and accessing the list directly.
Essentially, you are getting the same list, that is why there is no real time difference.
回答3:
TestEnum.class.getEnumConstants()
calls values()
internally through reflection (at least in my version - Oracle's Java 7): take a look at java.lang.Class.getEnumConstants()
and java.lang.Class.getEnumConstantsShared()
So it should only be slower by a reflection method lookup (probably constant time if a map is used) and by a clone of the result performed in getEnumConstants()
.
来源:https://stackoverflow.com/questions/32907575/comparison-of-enums-values-method-and-class-getenumconstants