每日一例 | forEach、forItem和forI的性能测试

云中志

共 3677字,需浏览 8分钟

 ·

2021-05-28 14:03


前言

日常开发中,for循环是我们最常用的循环之一,我们经常用他们来遍历各种集合,除了forI这种最基本的for循环,还有forItem这种增强的for循环,而且随着lambda表达式的诞生,jdk还为我们提供了另外一种循环遍历方式——forEach,但是我一直有个疑问,到底他们的性能如何呢,实际开发中我们应该如何选择呢?今天,我们就来探讨下这个问题。

性能测试

准备

开始之前,我们先写一段测试代码,这段代码的作用就是构建一个StringList,然后我们分别用他们三个进行循环遍历,分别计算用时

public static void main(String[] args) {
        int initSize = 100;
        List<String> stringList = new ArrayList<>(initSize);
        for (int i = 0; i < initSize; i++) {
            stringList.add(String.format("%d%s", i, "str"));
        }
        // forEach
        long startTimeForEach = System.currentTimeMillis();
        stringList.forEach(System.out::println);
        long endTImeForEach = System.currentTimeMillis();
        // for item
        long startTimeForItem= System.currentTimeMillis();
        for (String s : stringList) {
            System.out.println(s);
        }
        long endTimeForItem= System.currentTimeMillis();

        // for i
        long startTimeForI= System.currentTimeMillis();
        for (int i = 0; i < stringList.size(); i++) {
            System.out.println(stringList.get(i));
        }
        long endTimeForI= System.currentTimeMillis();

        System.out.println(String.format("List为%d时,forEach遍历用时:%d", initSize, (endTImeForEach - startTimeForEach)));
        System.out.println(String.format("List为%d时,forItem遍历用时:%d", initSize, (endTimeForItem - startTimeForItem)));
        System.out.println(String.format("List为%d时,forI遍历用时:%d", initSize, (endTimeForI - startTimeForI)));
    }

开始测试

初始值为100

我们先把List的初始化大小设为100,测试的结果表明,在此等数据量下,forIforItem的用时基本一致,多次运行,偶尔,forI表现会更好一点,但是forEach的时间性能就没那么优秀了,和前两都有着数量级的区别:

初始值为1,000

这时候,forIforItem的差距就体现出来了,后者比前者快了近一倍,当然,forEach性能依然表现最差。和100时相比,forI用时翻了6倍,forItem用时翻了5倍,forEach用时翻了不到两倍。

重复多次运行,forItemforI有差距,稳定在20左右,但不是很大,forEach稳定在200左右

初始值10,000

这时候的性能表现,竟然是forI最优,当然依然是forEach最差

多次运行也基本维持这个结论

初始值100,000

数据量达到十万的时候,forEach才慢慢开始有优势了,但是还是超不过forI

偶尔会有和结论相悖的结果的,但这种情况很少

大部分都是符合我们结论的

LinkedList

但如果把ArrayList改成LinkedList,数据量超过10,000基本上都是forI表现最差

100,000时
10,000
1000

这里还是forEach最差

100

forI最好

总结

上面的结论已然很直观了,综合表现forI最佳,forItem其次,最差的是forEach,但并不是说以后开发就只推荐你用forI,其实还是要看你具体业务的,如果你要用lambda表达式,那forEach就是最好的选择,你也没得选。当然,以上测试结果可能和环境也有关系(JDK1.8),毕竟12年的老爷机了,要啥自行车……

- END -


浏览 123
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报