Java 反射:为什么这么慢? [英] Java Reflection: Why is it so slow?

查看:79
本文介绍了Java 反射:为什么这么慢?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直避免使用 Java 反射,因为它以缓慢而著称.我在当前项目的设计中达到了一个点,能够使用它会使我的代码更具可读性和优雅性,所以我决定试一试.

I've always avoided Java reflection soley based on its reputation for slowness. I reached a point in the design of my current project where being able to use it would make my code much more readable and elegant, so I decided to give it a go.

我只是对这种差异感到惊讶,我注意到有时运行时间长了近 100 倍.即使在这个只是实例化一个空类的简单示例中,也令人难以置信.

I was simply astonished by the difference, I noticed at times almost 100x longer run times. Even in this simple example where it just instantiates an empty class, it's unbelievable.

class B {

}

public class Test {

    public static long timeDiff(long old) {
        return System.currentTimeMillis() - old;
    }

    public static void main(String args[]) throws Exception {

        long numTrials = (long) Math.pow(10, 7);

        long millis;

        millis = System.currentTimeMillis();

        for (int i=0; i<numTrials; i++) {
            new B();
        }
        System.out.println("Normal instaniation took: "
                 + timeDiff(millis) + "ms");

        millis = System.currentTimeMillis();

        Class<B> c = B.class;

        for (int i=0; i<numTrials; i++) {
            c.newInstance();
        }

        System.out.println("Reflecting instantiation took:" 
              + timeDiff(millis) + "ms");

    }
}

真的,我的问题是

  • 为什么这么慢?有什么我做错了吗?(即使是上面的例子也证明了差异).我很难相信它真的可以比正常实例化慢 100 倍.

  • Why is it this slow? Is there something I'm doing wrong? (even the example above demonstrates the difference). I have a hard time believing that it can really be 100x slower than normal instantiation.

还有什么可以更好地用于将代码视为数据的吗(请记住,我现在坚持使用 Java)

Is there something else that can be better used for treating code as Data (bear in mind I'm stuck with Java for now)

推荐答案

您的测试可能存在缺陷.一般虽然JVM可以优化正常的实例化,但无法针对反射用例进行优化.

Your test may be flawed. Generally though the JVM may optimize the normal instantiation but could not make optimizations for the reflective use case.

对于那些想知道时间是什么的人,我添加了一个预热阶段并使用一个数组来维护创建的对象(更类似于真实程序可能会做的事情).我在我的 OSX、jdk7 系统上运行了测试代码并得到了这个:

For those wondering what the times were, I added a warmup phase and used an array to maintain the created objects (more similar to what a real program might do). I ran the test code on my OSX, jdk7 system and got this:

反射实例化耗时:5180ms
正常实例化耗时:2001 毫秒

Reflecting instantiation took:5180ms
Normal instaniation took: 2001ms

修改测试:

public class Test {

    static class B {

    }

    public static long timeDiff(long old) {
        return System.nanoTime() - old;
    }

    public static void main(String args[]) throws Exception {

        int numTrials = 10000000;
        B[] bees = new B[numTrials];
        Class<B> c = B.class;
        for (int i = 0; i < numTrials; i++) {
            bees[i] = c.newInstance();
        }
        for (int i = 0; i < numTrials; i++) {
            bees[i] = new B();
        }

        long nanos;

        nanos = System.nanoTime();
        for (int i = 0; i < numTrials; i++) {
            bees[i] = c.newInstance();
        }
        System.out.println("Reflecting instantiation took:" + TimeUnit.NANOSECONDS.toMillis(timeDiff(nanos)) + "ms");

        nanos = System.nanoTime();
        for (int i = 0; i < numTrials; i++) {
            bees[i] = new B();
        }
        System.out.println("Normal instaniation took: " + TimeUnit.NANOSECONDS.toMillis(timeDiff(nanos)) + "ms");
    }


}

这篇关于Java 反射:为什么这么慢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆