JDK8 lambda表达式stream()与parallelStream()性能分析

版权声明:欢迎转载,注明作者和出处就好!如果不喜欢或文章存在明显的谬误,请留言说明原因再踩哦,谢谢,我也可以知道原因,不断进步!https://blog.csdn.net/csonst1017/article/details/86715772

在公司的项目里有很多的地方都是使用lambda表达式的stream()方法来遍历集合,但是用lambda表达式是否就能比普通遍历有更高的效率呢?是否仅仅只是个语法糖?这里我们使用普通的遍历方法来与lambda表达式的遍历进行对比分析。

1.stream()

我们先对stream()的forEach()进行遍历分析:

情况一(集合新增操作):
        List<String> list = new ArrayList<>();
        List<String> list2 = new ArrayList<>();
        for (int i = 0; i < 1000000; i++)
            list.add(String.valueOf(i));
        //lambda表达式
        long start = System.currentTimeMillis();
//       list.parallelStream().forEach((s)->{
//            list2.add(s.toString());
//        });
        //普通测试
        for (Object s : list) {
            list2.add(s.toString());
        }
        long end = System.currentTimeMillis();
        System.out.println("耗时:" + (end - start) + "  ms");

普通遍历:

多次测试消耗时间:
在这里插入图片描述在这里插入图片描述在这里插入图片描述

在这里插入图片描述在这里插入图片描述
平均耗时: 77ms

lambda表达式遍历:

多次测试消耗时间:
在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述
平均耗时: 52ms

对比普通遍历和lambda表达式的集合新增遍历操作,lambda比普通集合平均少消耗25ms的时间(当循环10W次时,2者差距可以忽略不计,这就是我为什么循环100W次的原因)。因为平时我们很少有超过1000000大小的集合,所以这里总结为使用两个方法去遍历都可以,性能差距忽略不计(如果涉及外部变量运算的话用普通循环,不涉及推荐用lambda(少写代码))。

情况二(数据库操作):
  List<String> list = new ArrayList<>();
        List<String> list2 = new ArrayList<>();
        for (int i = 0; i < 100; i++)
            list.add(String.valueOf(i));
        long start = System.currentTimeMillis();
        //lambda表达式
//        list.stream().forEach((s) -> {
//            productFrontMapper.selectByFrontView(null);
//        });
        //普通测试
        for (Object s : list) {
            productFrontMapper.selectByFrontView(null);
        }
        long end = System.currentTimeMillis();
        System.out.println("耗时:" + (end - start) + "  ms");

普通遍历:

多次测试消耗时间:
在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述
平均耗时: 724 ms

lambda表达式遍历:

多次测试消耗时间:
在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述
平均耗时: 637ms

对比普通遍历和lambda表达式的数据库操作,lambda比普通集合平均少消耗87ms的时间(当循环10次时,2者差距可以忽略不计,这就是我为什么循环100次数的原因)。当数据库操作次数很大时,推荐lambda表达式,如果只是循环几十次,那么两个方法差距很小。但是平时开发项目我们很少在大集合遍历时去执行数据库操作,所以两者都可以使用(如果涉及外部变量运算的话用普通循环,不涉及推荐用lambda(少写代码))。

2.parallelStream()

分析完stream()的性能接着我们来分析parallelStream()。
parallelStream()与stream()区别是parallelStream()使用多线程去并发遍历,而stream()是单线程。

情况一(集合新增操作):
   List<String> list = new ArrayList<>();
        List<String> list2 = new ArrayList<>();
        for (int i = 0; i < 1000000; i++)
            list.add(String.valueOf(i));
        long start = System.currentTimeMillis();
        //lambda表达式
//        list.parallelStream().forEach((s) -> {
//            list2.add(s.toString());
//        });
        //普通测试
        for (Object s : list) {
            list2.add(s.toString());
        }
        long end = System.currentTimeMillis();
        System.out.println("耗时:" + (end - start) + "  ms");

普通遍历:
耗时跟上面测试stream()是一样的,这里我就跳过了。

lambda表达式遍历:

多次测试消耗时间:
在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述
平均耗时: 47ms

由此可见,parallelStream()平均耗时是三者中最低的(针对非数据库操作),但是会有一个问题,因为使用parallelStream()要开放多线程和进行多线程间的切换,会消耗额外的资源,而且parallelStream()不是线程安全的,要进行额外的同步加锁操作。所以遍历时没有进行数据库操作的话,还是使用stream()和普通遍历吧。

情况二(数据库操作):
  List<String> list = new ArrayList<>();
        List<String> list2 = new ArrayList<>();
        for (int i = 0; i < 100; i++)
            list.add(String.valueOf(i));
        long start = System.currentTimeMillis();
        //lambda表达式
        list.parallelStream().forEach((s) -> {
            productFrontMapper.selectByFrontView(null);
        });
        //普通测试
//        for (Object s : list) {
//            list2.add(s.toString());
//        }
        long end = System.currentTimeMillis();
        System.out.println("耗时:" + (end - start) + "  ms");

普通遍历:
耗时同上。

lambda表达式遍历(重点):

多次测试消耗时间:

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

平均耗时: 271ms

可以看到,在数据库操作中,使用parallelStream()来遍历比用stream()和普通for循环遍历强了至少2倍多!所以在这里强烈建议当循环遍历中有数据库操作时,使用parallelStream()来进行遍历!

总结:

当循环遍历中不需要进行数据库操作时,使用stream()或普通循环来遍历(根据实际业务情况来选择用哪个)。
当循环遍历中(多次循环,百次以上)需要进行数据库操作时,使用parallelStream()来遍历,但是要注意多线程安全。

  • 4
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值