枚举值()方法与class.getEnumConstants()方法的比较



我试图比较这两种方法来实现枚举值(有和没有反射)。

这是我的测试类:

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));
    }
}

我对测试结果感到困惑。它们消耗的时间大致相同。我期待那门课。getEnumConstants会比values()方法慢得多。

结果:
使用反射耗时:6050
使用反射耗时:7483

JDK版本:

1.8.0_60

问题:
那么为什么在性能上没有差别呢?

那么为什么在性能上没有差别呢?

您自己的测试显示非反射方法大约快20%。这可能没有您期望的那么多,但这是一个重要的差异。

事实上,很难以任何方式概括你的结果。性能测试Java很棘手。特别是JIT编译可能会导致像您这样的合成基准产生只代表它们自己的结果,并且不能准确地描述在实际应用程序上下文中可以期望的性能。

无论如何,你提出的比较这两种方法的标准是错误的。只要可能,您就应该使用普通的非反射方法,因为它提供了更好的API,即使性能差异很小。曾经使用反射的唯一原因是,在运行时确定要采取的操作的细节之前,您无法了解足够的信息。

TestEnum.class.getEnumConstants()通过反射在内部调用values()(至少在我的版本- Oracle的Java 7中):看看java.lang.Class.getEnumConstants()java.lang.Class.getEnumConstantsShared()

所以它应该只通过反射方法查找(如果使用映射可能是常数时间)和在getEnumConstants()中执行的结果的克隆来减慢。

我对这些结果并不感到惊讶。

当java加载enum (Class对象中的值列表)时,它还将创建访问该列表(即values())的方法。

当你使用TestEnum.values();时,你会得到这个值列表,当你使用TestEnum.class.getEnumConstants();时,你所做的就是获取Class对象并直接访问列表。

基本上,你得到的是相同的列表,这就是为什么没有真正的时间差。

相关内容

  • 没有找到相关文章

最新更新