Java 核心技术面试精讲
杨晓峰
前 Oracle 首席工程师
125942 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 44 讲
Java 核心技术面试精讲
15
15
1.0x
00:00/00:00
登录|注册

第34讲 | 有人说“Lambda能让Java程序慢30倍”,你怎么看?

GC的影响
方法内联
常量折叠
无效代码消除
预热
构建步骤
选择JMH框架
程序诊断复杂性
初始化的开销
程序诊断复杂性
Lambda的启动过程
Lambda的性能差异
自动装箱、拆箱的开销
代码逻辑瑕疵
明确定义范围和目标
有效的通用手段
常用手段
计划和保证业务支撑能力
项目中的容量评估
保证微基准测试的正确性
构建微基准测试
目的和特征
保证基准测试的正确性
避免偏离测试目的
主流框架构建简单的基准测试
似是而非的“秘籍”
性能敏感场景下的局限性
强大的函数式编程能力
Lambda/Stream的性能差异
基准测试
判断是否符合业务支撑目标
评估Java应用性能
定量的、可对比的方法
性能评估和容量规划
微基准测试
基准测试的基础要素
Java 8中的Lambda特性
Lambda性能问题分析
性能问题分析的基本思路
性能评估和容量规划
微基准测试
基准测试的基础要素
Java 8中的Lambda特性
Lambda性能问题分析
性能问题分析的基本思路

该思维导图由 AI 生成,仅供参考

在上一讲中,我介绍了 Java 性能问题分析的一些基本思路。但在实际工作中,我们不能仅仅等待性能出现问题再去试图解决,而是需要定量的、可对比的方法,去评估 Java 应用性能,来判断其是否能够符合业务支撑目标。今天这一讲,我会介绍从 Java 开发者角度,如何从代码级别判断应用的性能表现,重点理解最广泛使用的基准测试(Benchmark)。
今天我要问你的问题是,有人说“Lambda 能让 Java 程序慢 30 倍”,你怎么看?
为了让你清楚地了解这个背景,请参考下面的代码片段。在实际运行中,基于 Lambda/Stream 的版本(lambdaMaxInteger),比传统的 for-each 版本(forEachLoopMaxInteger)慢很多。
// 一个大的ArrayList,内部是随机的整形数据
volatile List<Integer> integers = …
// 基准测试1
public int forEachLoopMaxInteger() {
int max = Integer.MIN_VALUE;
for (Integer n : integers) {
max = Integer.max(max, n);
}
return max;
}
// 基准测试2
public int lambdaMaxInteger() {
return integers.stream().reduce(Integer.MIN_VALUE, (a, b) -> Integer.max(a, b));
}

典型回答

我认为,“Lambda 能让 Java 程序慢 30 倍”这个争论实际反映了几个方面:
第一,基准测试是一个非常有效的通用手段,让我们以直观、量化的方式,判断程序在特定条件下的性能表现。
第二,基准测试必须明确定义自身的范围和目标,否则很有可能产生误导的结果。前面代码片段本身的逻辑就有瑕疵,更多的开销是源于自动装箱、拆箱(auto-boxing/unboxing),而不是源自 Lambda 和 Stream,所以得出的初始结论是没有说服力的。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

文章介绍了基准测试在评估Java程序性能时的重要性,以及Lambda表达式对程序性能的影响。作者指出了基准测试需要明确定义范围和目标,避免产生误导性的结果,并深入分析了Lambda表达式在特定场景下可能存在的性能差异,以及自动装箱/拆箱机制对性能的影响。此外,还介绍了如何构建微基准测试以及需要规避的风险点。总的来说,文章提醒读者在评估程序性能时需谨慎对待各种观点,以定量、定性的方式探究真相,为读者提供了对Java程序性能评估的全面认识。文章深入浅出,有助于读者更好地理解和应用Java语言的特性。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Java 核心技术面试精讲》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(9)

  • 最新
  • 精选
  • 蔡光明
    杨老师,我今天去面试的时候,java基础知识答的还可以,就是面试官扩展着问,问到spring和springcloud框架时就有些懵了,请问我现在应该如何学习,spring一直都是懂得不是很多,仅限于会用,杨老师能推荐一些相关的学习资料吗

    作者回复: 我后面会有篇Spring相关,但毕竟能覆盖很有限,我自己的理解角度和业务开发可能也不太一样; 如果是需要整体上的对比和介绍,类似知乎、博客之类有整理完善的,请查找一下; 但是,真正的深入还是需要系统性学习,相关书籍,阅读源码,上手实践

    2018-07-24
    24
  • yushing
    请问杨老师,无效代码消除后,mul的计算不执行了,那left和right也就没有使用了,是不是left和right的赋值语句也会被判断为无效代码不执行了呢?

    作者回复: 是的

    2018-07-24
    11
  • I
    那就是可以使用,凡涉及性能要求严格的情况下就不用。既然这样,Java费尽力气开发出一个性能不行的东西出来,只为了减少代码量和支持函数式吗,还有并行并没有带来想象中的优势吗,所谓的免费的并行,却不可以轻易免费使用,本人基础一般,望作者指点一二,谢谢!

    作者回复: 文章不是这个意思吧,性能影响没有那么明显,需要考虑到如此程度的是少数,易读、易维护往往更重要

    2018-07-27
    3
    6
  • spark
    专栏写的好,像流水和故事。大概技术像作者的开发人员可以毕业了
    2018-07-25
    8
    14
  • ddv
    lambda这一块如果能够单独拎出来说一说 比如他的底层实现是如何决定了他的效率 以及java在函数引用这一块的尝试 这是一个很有意思的语言特点 希望作者有空可以做一个专集
    2019-03-27
    6
  • 最好不过
    因为第一次调用lamda时初始化的开销比较大,会进行动态时生产lambda的相干类,加载额外的ASM框架,编译时间较长;因此如果我们测试本文的中的测试只是测试了第一次的调用的时间,当进行预热之后,lambda的测试时间和普通for循环相差不大。详细原因可以看这篇文章https://juejin.cn/post/6844904202439753741
    2021-06-06
    4
  • twc
    “Of course it’s not always the case, but in this pretty common example, it showed it can be around 5 times worse." 引用的文章说 lamda 在 " 普通”情况下, lamda是慢了 5倍。 杨老师在质疑 测试的环境不够标准,通篇读下来没有看到结论? 不知用了lamda 到底是快了还是慢了
    2020-07-23
    2
    2
  • 李飞
    对性能调优这块实操涉及的不多,先做学习吧,后期再回头学第二遍
    2020-05-17
    1
  • 张天屹
    lambda看起来有太多的缺点,那我们为什么要用他呢?我理解的是函数式编程在并行计算上的优势
    2019-04-09
收起评论
显示
设置
留言
9
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部