Java · 2020年12月30日 0

Java各种循环的性能比较

前言

好久不写东西了,得空写个与网上意见不那么统一的结论吧。
网上有很多资料都在说Java中for、foreach、lambda.forEach这几个之间谁更快,甚至有人说“性能甚至差出十几倍”,那这里就写个例子证明一下各个循环之间的效率问题。

循环中啥都不干

    @Test
    public void test1() {

        List<ProjectTaskCriteria> criteriaList = new ArrayList<>();
        for (int i = 0; i < 5000000; i++) {
            ProjectTaskCriteria criteria = new ProjectTaskCriteria();
            criteria.setProjectId((long) i);
            criteriaList.add(criteria);
        }

        long normalStart = System.currentTimeMillis();
        for (int i = 0; i < criteriaList.size(); i++) {
        }
        long normalEnd = System.currentTimeMillis();
        System.out.println("普通循环运行毫秒数===" + (normalEnd - normalStart));


        long normalStart1 = System.currentTimeMillis();
        for (int i = 0; i < criteriaList.size(); i++) {
            criteriaList.get(i);
        }
        long normalEnd1 = System.currentTimeMillis();
        System.out.println("普通1循环运行毫秒数===" + (normalEnd1 - normalStart1));


        long lambdaStart = System.currentTimeMillis();
        criteriaList.forEach(i -> {
        });
        long lambdaEnd = System.currentTimeMillis();
        System.out.println("lambda循环运行毫秒数===" + (lambdaEnd - lambdaStart));

    }

以下是执行结果,一共跑了三次;目前能得出来的结论就是:

  • 循环内啥也不干,性能确实有差距,但远远没有10倍以上(也不排除因个人环境、机器等的差异导致更大的差距)


与lambda循环相匹配的对比应该是第二个循环,而不是第一个;在lambda循环中,需要取出当前的对象;第一个循环是真的啥都没干;第二个循环,取得了当前对象与第三个循环对应。

循环中做点简单的事

 @Test
    public void test2() {

        List<ProjectTaskCriteria> criteriaList = new ArrayList<>();
        for (int i = 0; i < 5000000; i++) {
            ProjectTaskCriteria criteria = new ProjectTaskCriteria();
            criteria.setProjectId((long) i);
            criteriaList.add(criteria);
        }


        long normalStart = System.currentTimeMillis();
        for (ProjectTaskCriteria taskCriteria : criteriaList) {
            taskCriteria.setStartDate(LocalDateTime.now());
        }
        long normalEnd = System.currentTimeMillis();
        System.out.println("foreach普通循环运行毫秒数===" + (normalEnd - normalStart));


        long normalStart1 = System.currentTimeMillis();
        for (int i = 0; i < criteriaList.size(); i++) {
            ProjectTaskCriteria taskCriteria = criteriaList.get(i);
            taskCriteria.setStartDate(LocalDateTime.now());
        }
        long normalEnd1 = System.currentTimeMillis();
        System.out.println("普通循环运行毫秒数===" + (normalEnd1 - normalStart1));


        long lambdaStart = System.currentTimeMillis();
        criteriaList.forEach(i -> {
            i.setStartDate(LocalDateTime.now());
        });
        long lambdaEnd = System.currentTimeMillis();
        System.out.println("lambda循环运行毫秒数===" + (lambdaEnd - lambdaStart));

    }

看下边的执行结果




呃呃呃,只能说各有千秋,但性能差距并没有体现出来,甚至性能相当的接近;此处的结论就是:

  • 循环中但凡做一点点事情,就不可能出现好几倍的性能差异;因为我们在循环中写的业务代码越复杂,那么业务代码占用总时间、总比例就更多;for、foreach、lambda.forEach实现层面的差异占用的总时间就会越来越小,所以不能导致更大性能差异。

所以说再看见说for、foreach、lambda.forEach循环之间的性能差异几十倍之类因为性能问题不建议使用lambda.forEach诸如此类的言论,请直接忽略。

另外再说一句,互联网中的知识非常多,但不全都是可信的,有疑问一定要实践,实践出真知






>>转载请注明原文链接地址:Java各种循环的性能比较