java 类反射的效率_Java——反射三种方式的效率对比

本文对比了Java中通过field直接访问、使用BeanUtils以及通过Method.invoke()三种反射方式获取属性值的效率。实验结果显示,直接使用field效率最高,BeanUtils最慢,Method.invoke()居中。多次调用后,field访问方式的耗时呈现下降趋势,可能得益于缓存机制。
摘要由CSDN通过智能技术生成

转载自:https://blog.csdn.net/aitcax/article/details/52694423

1 使用field(效率最高)

long start = System.nanoTime();

Field[] fields = CallCount.class.getDeclaredFields();

for (String str : dateList) {

boolean exist = false;

for (Field field : fields){

field.setAccessible(true);

if (field.getName().endsWith(str)) {

int value = 0;

for (CallCount callCount : callCountList) {

value += (Integer)field.get(callCount);

}

resultList.add(value);

exist = true;

break;

}

}

if (!exist) {

resultList.add(0);

}

}

long end = System.nanoTime();

log.info("old call cost :" + (end-start));

2 使用 org.apache.commons.beanutils.BeanUtils来获取属性

long start = System.nanoTime();

for (String str : dateList) {

Integer value = getMinuteAccessCount(str, callCountList);

resultList.add(value);

}

long end = System.nanoTime();

log.info("new call cost :" + (end-start));

private Integer getMinuteAccessCount(String minute, List callCountList) {

Integer result = 0;

String propertyName = "logMinute" + minute;

for (CallCount callCount : callCountList) {

int value = 0;

try {

value = Integer.valueOf(BeanUtils.getProperty(callCount, propertyName));

} catch (NumberFormatException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {

e.printStackTrace();

}

result += value;

}

return result;

}

3  使用java.lang.reflect.Method获取值

long start = System.nanoTime();

for (String str : dateList) {

Integer value = getMinuteAccessCount(str, callCountList);

resultList.add(value);

}

long end = System.nanoTime();

log.info("new call cost :" + (end-start));

private Integer getMinuteAccessCount(String minute, List callCountList) {

Integer result = 0;

for (CallCount callCount : callCountList) {

int value = 0;

try {

Method method = callCount.getClass().getDeclaredMethod("getLogMinute"+minute);

Object obj = method.invoke(callCount);

value = (Integer)obj;

} catch (NumberFormatException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {

e.printStackTrace();

}

result += value;

}

return result;

}

4 耗时对比,在使用相同的查询条件,相同的数据的情况下。通过实验得到以下两组数据(耗时/纳秒)

1 old call cost :517599

1 old call cost :347916

1 old call cost :337312

1 old call cost :177893

1 old call cost :131709

1 old call cost :82789

1 old call cost :63973

3 new call cost :925383

3 new call cost :794016

3 new call cost :912382

1 old call cost :755016

1 old call cost :365364

1 old call cost :231944

1 old call cost :123498

1 old call cost :103315

1 old call cost :92025

1 old call cost :81762

2 new call cost :139741338

2 new call cost :3387140

2 new call cost :2230497

2 new call cost :9215854

2 new call cost :2313970

2 new call cost :1549374

2 new call cost :1884291

2 new call cost :1100880

2 new call cost :1488138

每组数据前的数字代表之前取值的方式。

由数据对比可以看出,耗时最小的,始终是方式1,并且方式1在多次调用时,耗时是逐步减少的,可能是有缓存机制。

耗时第二少的是方式3,耗时最多的是方式2.

5 解析

方式1,采用了最基本的java反射方式,使用Filed,循环bean的Field,得到Object,再转换为Integer类型。

方式2,采用了看似最简洁的BeanUitls,根据属性名,获取属性值。这样最耗时。

方式3,采用了获取bean的Method,然后invoke的方式来获取值。

---------------------

作者:aitcax

来源:CSDN

原文:https://blog.csdn.net/aitcax/article/details/52694423

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值