一、为什么需要延迟执行
- 问题引出:有些场景的代码执行后,结果不一定会被使用,从而造成性能浪费。
- 如何解决:Lambda表达式是可以延迟执行的,这正好可以作为解决方案,提升性能。
二、延迟执行造成的性能浪费的案例
- 典型的场景:就是对参数进行有条件使用,例如对日志消息进行拼接后,在满足条件的情况下进行打印输出:
public class LoggerDemo {
private static void log(int level, String msg) {
//条件判断
if (level == 1) {
System.out.println(msg);
}
}
public static void main(String[] args) {
String msgA = "Hello";
String msgB = "World";
String msgC = "Java";
//方法调用,必须提前拼接字符串造成性能浪费
log(1, msgA + msgB + msgC);
}
}
-
问题说明:这段代码存在问题,无论级别level是否满足要求,log 方法的第二个参数,也就是**三个字符串(msgA + msgB + msgC)**无论如何一定先会被拼接,然后再传入方法内进行级别判断if (level == 1)。
-
问题进一步分类分析:
a.如果判断通过,那么好,这种情况不会对性能产生影响;
b.如果判断不通过,那么我们之前在传入参数时进行三个字符串 (msgA + msgB + msgC)的操作不就是白做了吗,因为又不需要打印,那么用在拼接字符串上的时间不就等于白白浪费了,也就造成了性能浪费。 -
问题解决:那么如何不浪费这些性能呢?于是lambda表达式挺身而出,来拯救这些不应该被浪费的性能。
三、使用lambda表达式进行优化(延迟执行)
- 条件不通过花费的时间展示
public class LoggerDemo {
private static void log(int level, String msg) {
if (level == 1) {
System.out.println(msg);
}
}
public static void main(String[] args) {
String msgA = "Hello";
String msgB = "World";
String msgC = "Java";
long start = System.currentTimeMillis();
//1.条件不通过情况
log(2, msgA + msgB + msgC);
long end = System.currentTimeMillis();
System.out.println("未使用lambda表达式花费时间:"+(end-start));
}
}
结果:
未使用lambda表达式花费时间:49
- 条件通过的情况
public class LoggerDemo {
private static void log(int level, String msg) {
if (level == 1) {
System.out.println(msg);
}
}
public static void main(String[] args) {
String msgA = "Hello";
String msgB = "World";
String msgC = "Java";
long start = System.currentTimeMillis();
//2.条件通过情况
log(2, msgA + msgB + msgC);
long end = System.currentTimeMillis();
System.out.println("未使用lambda表达式花费时间:"+(end-start));
}
}
结果:
HelloWorldJava
未使用lambda表达式花费时间:48
- 结果分析:两个没有使用lambda表达式的方法在条件判断不通过和通过的情况下花费的时间分别是48和49,那么可见时间上可以说是没什么区别。可见条件不通过的情况下字符串的拼接造成了性能浪费。
- 条件不通过情况
public class LoggerDemo {
private static void log(int level, MessageBuilder builder) {
if (level == 1) {
System.out.println(builder.buildMessage());
}
}
public static void main(String[] args) {
String msgA = "Hello";
String msgB = "World";
String msgC = "Java";
long start = System.currentTimeMillis();
//1.条件不通过的情况
log(2, () -> {
System.out.println("Lambda执行!");
return msgA + msgB + msgC;
});
long end = System.currentTimeMillis();
System.out.println("未延迟执行花费时间:"+(end-start));
}
}
/==
* 下面这个是函数式接口,方便lambda表达式的使用。
*/
@FunctionalInterface
interface MessageBuilder {
String buildMessage();
}
结果:
未延迟执行花费时间:20
- 条件通过的情况下
public class LoggerDemo {
private static void log(int level, MessageBuilder builder) {
if (level == 1) {
System.out.println(builder.buildMessage());
}
}
public static void main(String[] args) {
String msgA = "Hello";
String msgB = "World";
String msgC = "Java";
long start = System.currentTimeMillis();
//1.条件通过的情况
log(1, () -> {
System.out.println("Lambda执行!");
return msgA + msgB + msgC;
});
long end = System.currentTimeMillis();
System.out.println("延迟执行花费时间:"+(end-start));
}
}
/==
* 下面这个是函数式接口,方便lambda表达式的使用。
*/
@FunctionalInterface
interface MessageBuilder {
String buildMessage();
}
结果:
Lambda执行!
HelloWorldJava
延迟执行花费时间:49
- 结果分析:可见不通过和通过的时间分别是20和48,提升了一倍多的性能,。可见使用了lambda表达式的延迟特性之后,可以提高一定条件下代码的性能。
四、分析lambda表达式为何能提升性能
* 说明:根据上面这幅图可以看出来,lambda表达式的延迟执行特性带来的性能提升非常大。
但是需要函数式接口的支持,小伙伴有时候需要自己定义函数式接口来实现lambda
表达式的延时执行特性。
五、总结
1.lambda表达式具有延迟执行的特性,在特定的场合下使用lambda表达式,会让你的程序效率有不小的提升。
2.但是使用lambda表达式需要和函数式接口配合使用,希望各位小伙伴使用lambda表达式之前还是需要做足功课。