Java中for、foreach、stream、parallelStream性能对比

硬件环境

        CPU: intel 14700KF

        内存:ddr5 7600 24g * 2

系统&软件版本

        windows11

        jdk版本:

                openjdk version "11.0.22" 2024-01-16 LTS
                OpenJDK Runtime Environment Corretto-11.0.22.7.1 (build 11.0.22+7-LTS)
                OpenJDK 64-Bit Server VM Corretto-11.0.22.7.1 (build 11.0.22+7-LTS, mixed mode)

测试方法介绍

模拟日常开发中简单的业务场景,一组存在ArrayList中的People对象的年龄>=18,标记为成年人,通过不同的遍历方式实现下面这段代码,并执行一定的次数,可体现出性能差异化的次数,次数过少可能会导致结果太接近。

        for (int j = 0; j < cycleTimes; j++) {
            for (int i = 0; i < arrayListSize; i++) {
                People people = ori.get(i);
                if (people.getAge() >= 18) {
                    people.setIsAdult(true);
                }
            }
        }

完整测试代码


public class TestOthers {
    public static class People {
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }
        public boolean isAdult() {
            return isAdult;
        }
        public void setIsAdult(boolean adult) {
            isAdult = adult;
        }
        public static Random getRandom() {
            return random;
        }
        public static void setRandom(Random random) {
            People.random = random;
        }
        int age;
        boolean isAdult;
        public static Random random = new Random();
        public People() {
            this.age = random.nextInt(120);
        }
    }

    /**
     *
     * @param arrayListSize 需要遍历的数组的个数
     * @param cycleTimes 执行次数,达到一定次数才能看出时间差异
     * @param diffLoopTypeTimeList 存储不同类型遍历的时间结果
     */
    public static void testPerformance(int arrayListSize, int cycleTimes, Map<String, List<Long>> diffLoopTypeTimeList) {
        List<People> ori = new ArrayList<>(arrayListSize);
        for (int i = 0; i < arrayListSize; i++) {
            ori.add(new People());
        }
        long t1 = System.currentTimeMillis();
        for (int j = 0; j < cycleTimes; j++) {
            for (int i = 0; i < arrayListSize; i++) {
                People people = ori.get(i);
                if (people.getAge() >= 18) {
                    people.setIsAdult(true);
                }
            }
        }
        long t2 = System.currentTimeMillis();
        for (int i = 0; i < cycleTimes; i++) {
            for (People people : ori) {
                if (people.getAge() >= 18) {
                    people.setIsAdult(true);
                }
            }
        }
        long t3 = System.currentTimeMillis();
        for (int i = 0; i < cycleTimes; i++) {
            ori.stream().filter((ele) -> ele.getAge() >= 18).forEach(ele -> ele.setIsAdult(true));
        }
        long t4 = System.currentTimeMillis();
        for (int i = 0; i < cycleTimes; i++) {
            ori.parallelStream().filter((ele) -> ele.getAge() >= 18).forEach(ele -> ele.setIsAdult(true));
        }
        long t5 = System.currentTimeMillis();
        collectResult(diffLoopTypeTimeList, t1, t2, t3, t4, t5);

    }

    public static void main(String[] args) throws InterruptedException {
        HashMap<String, List<Long>> diffLoopTimeList = new HashMap<>();
        //用不同方式,遍历200w次含20个元素的数组并做简单的判断和设置值
        int times = 1;
        for (int i = 0; i < times; i++) {
            testPerformance(20, 2000000, diffLoopTimeList);
        }        for (Map.Entry<String, List<Long>> stringListEntry : diffLoopTimeList.entrySet()) {
            System.out.println(stringListEntry.getKey() + " : " + stringListEntry.getValue() + "ms");
        }
    }

    private static void collectResult(Map<String, List<Long>> diffLoopTimeList, long t1, long t2, long t3, long t4, long t5) {
        List<Long> aFor = diffLoopTimeList.getOrDefault("for循环", new ArrayList<>(20));
        aFor.add(t2 - t1);
        diffLoopTimeList.put("for循环", aFor);
        List<Long> aForeach = diffLoopTimeList.getOrDefault("foreach循环", new ArrayList<>(20));
        aForeach.add(t3 - t2);
        diffLoopTimeList.put("foreach循环", aForeach);
        List<Long> aStream = diffLoopTimeList.getOrDefault("stream流", new ArrayList<>(20));
        aStream.add(t4 - t3);
        diffLoopTimeList.put("stream流", aStream);
        List<Long> aParallelStream = diffLoopTimeList.getOrDefault("parallelStream流", new ArrayList<>(20));
        aParallelStream.add(t5 - t4);
        diffLoopTimeList.put("parallelStream流", aParallelStream);
    }
}

测试过程和结果

测试一

20个元素的数组用4种方式遍历100w次

测试main方法:

结果:

for循环 : [17]ms
stream流 : [68]ms
foreach循环 : [35]ms
parallelStream流 : [16633]ms

初步结论:

        数组数量较小时,for循环性能最优,foreach循环次之,stream流稍微落后于另外两种方式,并行流的性能明显不如另外几种方式。

测试二

去掉并行流在测试另外三种方式,100w次遍历测试110次去掉最高和最低的五次。

测试main方法:

结果:

for循环 : 727ms
stream流 : 1810ms
foreach循环 : 894ms

结论:for循环和foreach循环遍历少量元素的list时性能优于流处理。

测试三

遍历1000w数据100次,对比性能。

测试main方法:

结果:

for循环 : [2590]ms
stream流 : [2197]ms
foreach循环 : [2874]ms
parallelStream流 : [662]ms

结论:

数据量较大时,并行流效率远大于另外几种方式。

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值