Comparison of enums values() method and class.getEnumConstants()

懵懂的女人 提交于 2021-02-18 19:33:38

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!