为什么Java反射调用比方法调用更快?

时间:2013-08-05 18:18:48

标签: java performance reflection execution

我做了这个发现并用我的应用程序测试了它。 我正在调用并调用相同的方法。

我尝试了不同的连续执行以及不同的方法(加密,排序等等)并获得了以下结果。

Executions|Invoke-Call ratio

1         | 62,78%

10        | 107,58%

100       | 76,74%

1000      | 80,01%

10000     | 116,88%

100000    | 82,80%

1000000   | 91,67%

我检查过它是否可能是多线程的使用,但它不是我能说的。 可能是什么解释?

进一步澄清我的基准的摘录: 调用部分:

Executable executable = new Executable();
Method execute = executable.getClass().getMethod("execute");
System.out.println("# Startup finished.");
for (float i = 0; i <= 6; i++)
{
    int executions = (int) Math.pow(10, i);
    long start = System.nanoTime();
    for (int j = 0; j <= executions - 1; j++)
    {
        execute.invoke(executable);
    }
    long stop = System.nanoTime();
    long delta = stop - start;
    System.out.println("Invoke;" + executions + ";" + delta);
}
System.out.println("# Shutdown finished.");

通话部分:

Executable executable = new Executable();
System.out.println("# Startup finished.");
for (float i = 0; i <= 6; i++)
{
    int executions = (int) Math.pow(10, i);
    long start = System.nanoTime();
    for (int j = 0; j <= executions - 1; j++)
    {
        executable.execute();
    }
    long stop = System.nanoTime();
    long delta = stop - start;
    System.out.println("Invoke;" + executions + ";" + delta);
}
System.out.println("# Shutdown finished.");

对于这个Executable类的例子,我特别注意从execute方法中排除所有准备工作。

public class Executable
{
    private int index = 0;
    private int testsize = 1111111;
    private byte[][] plain = new byte[testsize][];
    private byte[][] hashed = new byte[testsize][];
    private SecureRandom securerandom;
    private MessageDigest messagedigest;

    public Executable()
    {
        this.securerandom = new SecureRandom();
        this.messagedigest = MessageDigest.getInstance("SHA-256");
        for (int i = 0; i <= testsize - 1; i++)
        {
            this.plain[i] = new byte[8];
            this.securerandom.nextBytes(this.plain[i]);
        }
    }

    public void execute()
    {
        messagedigest.update(this.plain[index]);
        this.hashed[index] = messagedigest.digest();
        index++;
    }
}

1 个答案:

答案 0 :(得分:3)

为了感兴趣的人,代码按预期工作,并且调用比调用快。

# Startup finished.
Invoke  1   1683969
Invoke  10  1876447
Invoke  100 23376245
Invoke  1000    29035955
Invoke  10000   55816067
Invoke  100000  209290359
# Shutdown finished.
# Startup finished.
Call    1   64587
Call    10  18820
Call    100 209160
Call    1000    1656594
Call    10000   17318746
Call    100000  167565824
# Shutdown finished.