所以我知道之前已经完成了这个主题,例如Java Reflection Performance,但我的特殊问题是,似乎很多流行的库都是通过注释和反射来实现的(例如Gson,Jackson,Jaxb实现,hibernate搜索).许多(如果不是全部)库提供良好(或很好)的性能,即使它们使用反射.我的问题是,他们是如何做到的?是否有一些"技巧"要知道或者他们只是使用直接反射,而表演的担忧是夸大其词?
编辑:例如,当我们写:MyObject obj = new Gson().fromJson(someInputStream,MyObject.class);
我可以理解库如何在内部缓存Field对象,但在我看来,它需要每次都反射性地实例化对象,并且它需要根据json的解析值调用每个字段上的setter(反射) .或者有没有办法只在启动时支付(全部)反射成本?
我肯定注意到Gson/Jackson等具有相对较大的启动成本,之后非常快.所以很明显我想知道,如果我写一个模糊相似的图书馆,我需要了解一些技巧吗?因为看起来你无法在每次通话时远离一些反射.
Osc*_*Ryz 10
成本高昂的是方法查找,但方法调用一次非常相似.
因此,一旦找到要调用的方法,就可以保留对它的引用,并且连续调用的工作方式类似.
当然,有些情况下您希望减少每毫秒.
虽然您应该知道微基准测试,但您可以尝试这样做只是为了得到一个粗略的想法:
import java.lang.reflect.*;
class ReflectionOrNot {
public void run() {
try {
Thread.currentThread().sleep( 0 );
} catch( InterruptedException ie ){}
}
public static void main( String ... args ) throws Exception {
ReflectionOrNot ron = new ReflectionOrNot();
int max = 1000000;
long start = System.currentTimeMillis();
for( int i = 0 ; i < max ; i++ ) {
ron.run();
}
System.out.println( "Direct access took: " + ( System.currentTimeMillis() - start ) );
Method m = ReflectionOrNot.class.getDeclaredMethod("run");
start = System.currentTimeMillis();
for( int i = 0 ; i < max ; i++ ) {
m.invoke( ron );
}
System.out.println( "Reflection Took: " + ( System.currentTimeMillis() - start ) );
start = System.currentTimeMillis();
for( int i = 0 ; i < max ; i++ ) {
m = ReflectionOrNot.class.getDeclaredMethod("run");
m.invoke( ron );
}
System.out.println( "Lookup + Reflect : " + ( System.currentTimeMillis() - start ) );
}
}
Run Code Online (Sandbox Code Playgroud)
用不同的方法召唤100万次让我:
C:\Users\oreyes\java>java ReflectionOrNot
Direct access took: 422
Reflection Took: 1156
Lookup + Reflect : 3016
C:\Users\oreyes\java>java ReflectionOrNot
Direct access took: 422
Reflection Took: 1125
Lookup + Reflect : 2750
C:\Users\oreyes\java>java ReflectionOrNot
Direct access took: 485
Reflection Took: 1203
Lookup + Reflect : 2797
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5227 次 |
| 最近记录: |