gpt4 book ai didi

java - 解读Java反射性能: Why is it surprisingly very fast?

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:12:58 25 4
gpt4 key购买 nike

我看到其他线程说 java 反射性能比使用非反射调用时慢 10-100 倍。

我在 1.6 中的测试表明情况并非如此,但我发现了一些其他有趣的事情,我需要有人向我解释。

我有实现我的接口(interface)的对象。我做了三件事 1) 使用对对象的引用我将该对象转换为接口(interface)并通过接口(interface)调用方法 2) 使用对实际对象的引用直接调用方法 3) 通过反射调用方法。我看到 #1 接口(interface)调用最快,紧随其后的是 #3 反射,但我注意到直接方法调用是最慢的。

我不明白,我希望直接调用最快,然后是接口(interface),然后反射会慢得多。

Blah 和 ComplexClass 与主类位于不同的包中,并且都有一个 doSomething(int x) 方法来实现接口(interface)并只打印整数 x。

这是我的结果(时间以毫秒为单位,多次试验的结果非常相似):直接调用方法:107194直接从转换为接口(interface)的对象调用方法:89594通过反射调用方法:90453

这是我的代码:

public class Main
{

/**
* @param args the command line arguments
*/
public static void main(String[] args)
{
Blah x = new Blah();
ComplexClass cc = new ComplexClass();
test((Object) x, cc);
}

public static void test(Object x, ComplexClass cc)
{
long start, end;
long time1, time2, time3 = 0;
int numToDo = 1000000;
MyInterface interfaceClass = (MyInterface) x;

//warming up the cache
for (int i = 0; i < numToDo; i++)
{
cc.doSomething(i); //calls a method directly
}

start = System.currentTimeMillis();
for (int i = 0; i < numToDo; i++)
{
cc.doSomething(i); //calls a method directly
}
end = System.currentTimeMillis();
time1 = end - start;

start = System.currentTimeMillis();
for (int i = 0; i < numToDo; i++)
{
interfaceClass.doSomething(i); //casts an object to an interface then calls the method
}
end = System.currentTimeMillis();
time2 = end - start;


try
{
Class xClass = x.getClass();
Class[] argTypes =
{
int.class
};
Method m = xClass.getMethod("doSomething", argTypes);
Object[] paramList = new Object[1];
start = System.currentTimeMillis();
for (int i = 0; i < numToDo; i++)
{
paramList[0] = i;
m.invoke(x, paramList); //calls via reflection
}
end = System.currentTimeMillis();
time3 = end - start;

} catch (Exception ex)
{
}

System.out.println("calling a method directly: " + time1);
System.out.println("calling a method directly from an object cast to an interface: " + time2);
System.out.println("calling a method through reflection: " + time3);
}

最佳答案

将所有测试放在同一个程序中是一个微基准测试错误 - Java 性能有一定的预热。这是最重要的失败。

将您的测试放在单独的程序中。然后多次运行测试,以便您了解预热何时完成以及统计显着性。

还有一个包含内部循环的巨大方法。 Hotspot 似乎比以前更擅长处理这个问题,但它仍然不够好。

您应该会发现,使用 -server 在紧密循环中调用虚方法(即使由不同的类加载器加载)会得到完全优化。因此,说直接调用比反射调用快多少没有多大意义。

关于java - 解读Java反射性能: Why is it surprisingly very fast?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1122506/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com