java.lang.reflect.Field
get
使用反射(和set
函数)而不是调用对象本身的set
and来设置和获取对象属性get
会导致任何显着的性能差异吗?
问问题
5153 次
3 回答
6
是的,基准测试很容易在 15 分钟内编写完成。
生成的代码更好,即使你缓存了反射访问器,我也试过了。
这是在 Java 7 64 位下:
import java.lang.reflect.Field;
class Data {
public double _value;
public double getValue() { return _value; }
public void setValue( double value ) { _value = value; }
}
public class Reflect {
public static final int LOOP_COUNT = 100_000_000;
public static void main( String[] args ) throws Throwable {
Data d = new Data();
long start = System.currentTimeMillis();
for( int i = 0; i < LOOP_COUNT; ++i ) {
d.setValue( i );
}
System.err.println( System.currentTimeMillis() - start );
Field field = Data.class.getDeclaredField( "_value" );
start = System.currentTimeMillis();
for( int i = 0; i < LOOP_COUNT; ++i ) {
field.set( d, new Double( i ));
}
System.err.println( System.currentTimeMillis() - start );
field.setAccessible( true ); // Optimization
start = System.currentTimeMillis();
for( int i = 0; i < LOOP_COUNT; ++i ) {
field.set( d, new Double( i ));
}
System.err.println( System.currentTimeMillis() - start );
}
}
结果:
20
37381
1677
比率接近 1870,没有设置可访问标志。设置它会使比率下降到 83。
于 2012-10-21T08:08:09.500 回答
0
是的,它确实会产生显着的性能差异,并且网络上有很多基准测试结果可以支持这一点。
例如: http: //www.cowtowncoder.com/blog/archives/2007/02/entry_32.html - 这似乎是说对 a get
orset
方法的反射调用比直接访问/更新字段慢约 50 倍. (并且使用方法获取/设置Field
仍然更慢。)
现在这些结果相当陈旧,并且(显然)反射的性能在最近的 HotSpot JVM 中得到了改进。即便如此,粗略的经验法则是“一个数量级或更慢”。
于 2012-10-21T08:28:25.623 回答
0
我运行了一个稍微修改过的版本:
public class Test {
private static class Data {
public double _value;
public void setValue(double value) {
_value = value;
}
}
public static final int LOOP_COUNT = 100_000_000;
public static void main(String[] args) throws Throwable {
Data d = new Data();
Random testing = new Random(5);
long start = System.currentTimeMillis();
for (int i = 0; i < LOOP_COUNT; ++i) {
d.setValue(testing.nextDouble());
}
System.err.println(System.currentTimeMillis() - start);
Field field = Data.class.getDeclaredField("_value");
testing = new Random(5);
start = System.currentTimeMillis();
for (int i = 0; i < LOOP_COUNT; ++i) {
field.setDouble(d, testing.nextDouble());
}
System.err.println(System.currentTimeMillis() - start);
testing = new Random(5);
field.setAccessible(true); // Optimization
start = System.currentTimeMillis();
for (int i = 0; i < LOOP_COUNT; ++i) {
field.setDouble(d, testing.nextDouble());
}
System.err.println(System.currentTimeMillis() - start);
}
}
结果(在 Java 1.8.0_121 和我的电脑上):
2714
2741
2625
似乎反射实际上更快。没想到这...
于 2020-04-14T19:15:51.430 回答