Java性能优化细节之for循环

看完https://blog.csdn.net/wh_forever/article/details/79203338这篇博客,实际动手测试,发现了一些问题,代码的编写果然充满了魅力,自己不试试哪能知道到底怎么样,建议大家也试试,平时注意代码编写的细节可以让我们编写更优秀的代码。

本机软件环境,JDK1.8  IDEA2019.2

1、嵌套循环

package cn.waggag.performance;

/**
 * @description:
 * @author: waggag
 * @time: 2019/7/30 19:42
 * @Company http://www.waggag.cn
 */
public class Test {
    private static long startTime;
    private static long endTime;

    public static void main(String[] args) {
        /**
         * Returns the current value of the running Java Virtual Machine's
         * high-resolution time source, in nanoseconds.
         * nanoTime()
         * 返回最准确的可用系统计时器的当前值,以毫微秒为单位。
         */
        //优化前
        startTime = System.nanoTime();
        for (int i = 0; i <10 ; i++) {
            for (int j = 0; j < 1000000000; j++) {
            }
        }
        endTime = System.nanoTime();
        System.out.println("外小内大耗时:"+(endTime - startTime));

        //优化后
        startTime = System.nanoTime();
        for (int i = 0; i < 1000000000; i++) {
            for (int j = 0; j < 10; j++) {
            }
        }
        endTime = System.nanoTime();
        System.out.println("外大内小耗时:"+ (endTime - startTime));
    }
}

两者耗时对比:

外小内大耗时:4430900
外大内小耗时:1978300

Process finished with exit code 0

结论:优化后性能提升了一倍,嵌套循环应该遵循“外小内大”的原则,这就好比你复制很多个小文件和复制几个大文件的区别。

2、尽量减少对变量的重复计算

package cn.waggag.performance;

/**
 * @description:
 * @author: waggag
 * @time: 2019/7/30 19:42
 * @Company http://www.waggag.cn
 */
public class Test2 {
    private static long stratTime;
    private static long endTime;

    public static void main(String[] args) {
        //优化前
        int a = 1;
        int b = 1;
        stratTime = System.nanoTime();
        for (int i = 0; i < 100000000; i++) {
            i = i * a * b;
        }
        endTime = System.nanoTime();
        System.out.println("未提取耗时:" + (endTime - stratTime));
        //优化后
        int c = a * b;
        stratTime = System.nanoTime();
        for (int i = 0; i < 100000000; i++) {
            i = i * c;
        }
        endTime = System.nanoTime();
        System.out.println("提取耗时:  " + (endTime - stratTime));
    }
}

两者耗时对比:

未提取耗时:2464103700
提取耗时:  1390659100

Process finished with exit code 0

结论:尽量将表达式的计算放到循环体的外面,可以有不错的性能提升。

3、减少循环体内的方法调用

package cn.waggag.performance;

import java.util.ArrayList;

/**
 * @description:
 * @author: waggag
 * @time: 2019/7/30 19:42
 * @Company http://www.waggag.cn
 */
public class Test3 {
    private static long stratTime;
    private static long endTime;

    public static void main(String[] args) {
        ArrayList<Object> list = new ArrayList<>();
        for (int i = 0; i < 100000; i++) {
            list.add(i);
        }
        //优化前
        stratTime = System.nanoTime();
        for (int i = 0; i < list.size(); i++) {
        }
        endTime = System.nanoTime();
        System.out.println("未优化list耗时:" + (endTime - stratTime));
        //优化后
        int len = list.size();
        stratTime = System.nanoTime();
        for (int i = 0; i < len; i++) {
        }
        endTime = System.nanoTime();
        System.out.println("优化list耗时:" + (endTime - stratTime));

    }
}

两者耗时对比:

未优化list耗时:478900
优化list耗时:  306100

Process finished with exit code 0

 结论:在循环体内尽量减少不必要的方法的调用,上例list.size()在循环体内每次循环都会被执行一次,无疑会影响程序的性能,所以应该将其放到循环外面,用一个变量来代替。

4、尽量将循环体放在异常捕获中

package cn.waggag.performance;
/**
 * @description:
 * @author: waggag
 * @time: 2019/7/30 19:42
 * @Company http://www.waggag.cn
 */
public class Test4 {
    private static long stratTime;
    private static long endTime;
    public static void test() {
        //优化前
        stratTime = System.nanoTime();
        for (int i = 0; i < 100000000; i++) {
            try {
            } catch (Exception e) {
            }
        }
        endTime = System.nanoTime();
        System.out.println("在内部捕获异常耗时:" + (endTime - stratTime));
        //优化后
        stratTime = System.nanoTime();
        try {
            for (int i = 0; i < 100000000; i++) {
            }
        } catch (Exception e) {
        }
        endTime = System.nanoTime();
        System.out.println("在外部捕获异常耗时:" + (endTime - stratTime));
    }

    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            test();
            System.out.println("====================");
        }
    }
}

两者耗时对比:

在内部捕获异常耗时:2884800
在外部捕获异常耗时:2168200
====================
在内部捕获异常耗时:8253700
在外部捕获异常耗时:100
====================
在内部捕获异常耗时:47500
在外部捕获异常耗时:0
====================
在内部捕获异常耗时:62300
在外部捕获异常耗时:100
====================
在内部捕获异常耗时:69800
在外部捕获异常耗时:0
====================
在内部捕获异常耗时:73100
在外部捕获异常耗时:100
====================
在内部捕获异常耗时:71600
在外部捕获异常耗时:100
====================
在内部捕获异常耗时:47200
在外部捕获异常耗时:0
====================
在内部捕获异常耗时:72400
在外部捕获异常耗时:0
====================
在内部捕获异常耗时:144500
在外部捕获异常耗时:100
====================

Process finished with exit code 0

 结论:实际多次运行发现性能差距不大,在循环体内大量运行后发现在外部捕获异常更容易被JVM认定为内联函数,所以将try catch放到循环外部,JVM优化后同样有不错的性能提升。

链接:https://share.weiyun.com/5OIvwj2  密码:d48wz9

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值