@Getter
@AllArgsConstructor
public class Bean {
int id;
}
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
long startTime = System.currentTimeMillis();
Method methodGetId = Bean.class.getMethod("getId");
Bean bean = new Bean(33);
int value = (int) methodGetId.invoke(bean);
log.info("java反射获取value:{},耗时{}ms",value,System.currentTimeMillis()-startTime);
startTime = System.currentTimeMillis();
ToIntFunction<Bean> function = Bean::getId;
Bean bean1 = new Bean(33);
int i = function.applyAsInt(bean1);
log.info("Lambda函数获取value:{},耗时{}ms",i,System.currentTimeMillis()-startTime);
}
控制台输出:

对于一次的操作,java反射表现要比Lambda生成函数映射的性能高。
如果将反射invoke操作和lambda生成函数映射执行100_000次呢?
private static final int N = 100_000;
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
long startTime = System.currentTimeMillis();
Bean bean = new Bean(33);
for (int i=0;i<N;i++){
Method methodGetId = Bean.class.getMethod("getId");
methodGetId.invoke(bean);
}
log.info("java反射获取耗时{}ms",System.currentTimeMillis()-startTime);
startTime = System.currentTimeMillis();
Bean bean1 = new Bean(33);
for (int i=0;i<N;i++){
ToIntFunction<Bean> function = Bean::getId;
function.applyAsInt(bean1);
}
log.info("Lambda生成函数映射耗时{}ms",System.currentTimeMillis()-startTime);
}
控制台输出:

处理速度相差约23倍,性能居然提升了这么多。
答案——Lambda 利用 LambdaMetafactory 生成了函数映射代替反射。
生成的函数映射进行函数复用,将一个固定签名的函数缓存起来,下次调用就可以省去函数创建的过程。

文章通过对比测试展示了在Java中,使用Lambda表达式生成的函数映射相比反射操作具有显著的性能优势。Lambda利用LambdaMetafactory生成的函数映射可以被缓存,从而在多次调用时避免了函数创建的开销,提高了执行效率。测试结果显示,处理相同次数的操作,Lambda的性能大约是反射的23倍。
171万+

被折叠的 条评论
为什么被折叠?



