【Java】Java中使用HashMap优化多层for循环嵌套以及for循环之性能优化

您所在的位置:网站首页 javafor循环嵌套实例 【Java】Java中使用HashMap优化多层for循环嵌套以及for循环之性能优化

【Java】Java中使用HashMap优化多层for循环嵌套以及for循环之性能优化

2024-06-20 18:15| 来源: 网络整理| 查看: 265

文章目录 前言使用HashMap优化多级嵌套循环优化前优化后for循环之性能优化嵌套循环外大内小嵌套外小内大嵌套分析总结 循环变量的实例化分析总结 提取与循环无关的表达式没有提取无关的表达式提取了无关的表达式分析总结 消除循环终止判断时的方法调用优化后分析总结 异常捕获在内部捕获异常在外部捕获异常分析总结:

前言

for循环是开发时常用的语法之一,比如对数组,集合的遍历等,但是如果使用不好也会出现很多新能损耗的问题,今天就来讲解一下for循环的常用性能优化问题。

for循环 里面还有 for循环, 然后做一些数据匹配、处理 这种场景。

使用HashMap优化多级嵌套循环

m层嵌套的n次的for循环的时间复杂度为O(n^m),如下所示:

优化前 public class forTradition { public static void main(String[] args){ List stus = new ArrayList(); // 为stus写入10条数据 ... 略 List gs = new ArrayList(); // 为gs写入10条数据 ... 略 for (int i = 0 ; i Grade g = gs.get(j); if( id == g.getStuId() ) { System.out.println( "学生:" + stuName + ",成绩:" + g.getValue() ); } } } } 优化后 public class forNew { public static void main(String[] args){ List stus = new ArrayList(); // 为stus写入10条数据 ... 略 List gs = new ArrayList(); // 为gs写入10条数据 ... 略 Map gradesMap = gs.stream().collect(Collectors.toMap( data -> data.getStuId() , data -> data.getValue() ); for (int i = 0 ; i System.out.println( "学生:" + stu.getName() + ",成绩:" + value ); } } } } for循环之性能优化 嵌套循环

嵌套循环是有俩层或者俩层以上的循环嵌套在一起,下面直接上代码说明。

外大内小嵌套 /** * 大循环驱动小循环(即外大内小) */ private static void bigSmall() { long stratTime = System.nanoTime(); for (int i = 0; i } } long endTime = System.nanoTime(); System.out.println("外大内小耗时:" + (endTime - stratTime)); }

执行看一下结果耗时:

外大内小耗时:8743800

再看看外小内大耗时情况

外小内大嵌套 /** * 小循环驱动大循环(即外小内大) */ private static void smallBig() { long stratTime = System.nanoTime(); for (int i = 0; i } } long endTime = System.nanoTime(); System.out.println("外小内大耗时:" + (endTime - stratTime)); }

执行看一下结果耗时:

外小内大耗时:6922600

好了,综合比较一下俩者的执行时间,时差还是很大的。

外小内大耗时:6922600 ;外大内小耗时:8743800

分析总结

由以上对比可知,优化后性能显著提升。嵌套循环应该遵循“外小内大”的原则,虽然循环次数没变,但是耗时却长了很大。这就好比你复制很多个小文件和复制几个大文件的区别,虽然总的大小没变,但是复制大文件明显比多个小文件更快。

循环变量的实例化

把循环变量的实例放在循环内:

/** * 循环变量放在循环内 */ private static void smallBigBetterTwo() { long stratTime = System.nanoTime(); for (int i = 0; i } } long endTime = System.nanoTime(); System.out.println("循环内变量耗时:" + (endTime - stratTime)); }

执行耗时:

循环内变量耗时:4934500

把循环变量的实例放在循环之外:

/**

循环变量放在循环外 */ private static void smallBigBetter() { long stratTime = System.nanoTime(); int i, j; for (i = 0; i < 100; i++) { for (j = 0; j < 10000000; j++) {

}

} long endTime = System.nanoTime(); System.out.println(“循环外变量耗时:” + (endTime - stratTime)); }

执行耗时:

循环外变量耗时:5013800

对比一下把变量放在循环内和循环外对比耗时,发现时差还是挺大的:

循环内变量耗时:4934500;循环外变量耗时:5013800

分析总结

虽然优化效果并不明显,但是随着循环次数的增加,耗时会越来越大,优化效果则会越来越明显。分析:优化前需要实例化1+i=101次,优化后仅仅2次。总结:循环变量的实例化应放在循环外。

提取与循环无关的表达式 没有提取无关的表达式 /** * 未提取无关的表达式 */ private static void calculationInner() { int a = 3; int b = 7; long stratTime = System.nanoTime(); for (int i = 0; i int a = 3; int b = 7; int c = a * b; long stratTime = System.nanoTime(); for (int i = 0; i } endTime = System.nanoTime(); System.out.println("未优化list耗时:"+(endTime - stratTime));

耗时:

未优化list耗时:253800 优化后 stratTime = System.nanoTime(); int size = list.size(); for (int i = 0; i long stratTime = System.nanoTime(); for (int i = 0; i } catch (Exception e) { } } long endTime = System.nanoTime(); System.out.println("在内部捕获异常耗时:" + (endTime - stratTime)); }

执行耗时:

在内部捕获异常耗时:3352700 在外部捕获异常 /** * 在外部捕获异常 */ private static void catchOuter() { long stratTime = System.nanoTime(); try { for (int i = 0; i } long endTime = System.nanoTime(); System.out.println("在外部捕获异常耗时:" + (endTime - stratTime)); }

执行耗时:

在外部捕获异常耗时:2893600 分析总结:

捕获异常很占用资源,所以不要把try catch放到循环内部,优化后性能同样有好几个数量级的提升。另外, 《Effective Java》一书指出for-each循环优先于传统的for循环,它在简洁性和预防bug方面有着传统for循环无法媲美的优势,并且,没有性能方面的损失,因此,推荐使用for-each循环。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3