for循环嵌套 简单优化
1 案例描述
某日,在JavaEye上看到一道面试题,题目是这样的:请对以下的代码进行优化
- for (int i = 0; i < 1000; i++)
- for (int j = 0; j < 100; j++)
- for (int k = 0; k < 10; k++)
- testFunction (i, j, k);
(注:为了同后面的内容一致,这里对原题目进行了部分修改)
2 案例分析
从给出的代码可知,不论如何优化,testFunction执行的次数都是相同的,该部分不存在优化的可能。那么,代码的优化只能从循环变量i、j、k的实例化、初始化、比较、自增等方面的耗时上进行分析。
首先,我们先分析原题代码循环变量在实例化、初始化、比较、自增等方面的耗时情况:
变量 | 实例化(次数) | 初始化(次数) | 比较(次数) | 自增(次数) |
i | 1 | 1 | 1000 | 1000 |
j | 1000 | 1000 | 1000 * 100 | 1000 * 100 |
k | 1000 * 100 | 1000 * 100 | 1000 * 100 * 10 | 1000 * 100 * 10 |
(注:由于单次耗时视不同机器配置而不同,上表相关耗时采用处理的次数进行说明)
该代码的性能优化就是尽可能减少循环变量i、j、k的实例化、初始化、比较、自增的次数,同时,不能引进其它可能的运算耗时。
3 解决过程
从案例分析,对于原题代码,我们提出有两种优化方案:
3.1 优化方案一
代码如下:
- for (int i = 0; i < 10; i++)
- for (int j = 0; j < 100; j++)
- for (int k = 0; k < 1000; k++)
- testFunction (k, j, i);
该方案主要是将循环次数最少的放到外面,循环次数最多的放里面,这样可以最大程度的(注:3个不同次数的循环变量共有6种排列组合情况,此种组合为最优)减少相关循环变量的实例化次数、初始化次数、比较次数、自增次数,方案耗时情况如下:
变量 | 实例化(次数) | 初始化(次数) | 比较(次数) | 自增(次数) |
i | 1 | 1 | 10 | 10 |
j | 10 | 10 | 10 * 100 | 10 * 100 |
k | 10 * 100 | 10 * 100 | 10 * 100 * 1000 | 10 * 100 * 1000 |
3.2 优化方案二
代码如下:
- int i, j, k;
- for (i = 0; i < 10; i++)
- for (j = 0; j < 100; j++)
- for (k = 0; k < 1000; k++)
- testFunction (k, j, i);
该方案在方案一的基础上,将循环变量的实例化放到循环外,这样可以进一步减少相关循环变量的实例化次数,方案耗时情况如下:
变量 | 实例化(次数) | 初始化(次数) | 比较(次数) | 自增(次数) |
i | 1 | 1 | 10 | 10 |
j | 1 | 10 | 10 * 100 | 10 * 100 |
k | 1 | 10 * 100 | 10 * 100 * 1000 | 10 * 100 * 1000 |
4 解决结果
那么,提出的优化方案是否如我们分析的那样有了性能上的提升了呢?我们编写一些测试代码进行验证,数据更能说明我们的优化效果。
4.1 测试代码
- public static void testFunction(int i, int j, int k) {
- System.out.print(""); // 注:该方法不影响整体优化,这里只有简单输出
- }
- public static void testA() {
- long start = System.nanoTime();
- for (int i = 0; i < 1000; i++)
- for (int j = 0; j < 100; j++)
- for (int k = 0; k < 10; k++)
- testFunction(i, j, k);
- System.out.println("testA time>>" + (System.nanoTime() - start));
- }
- public static void testB() {
- long start = System.nanoTime();
- for (int i = 0; i < 10; i++)
- for (int j = 0; j < 100; j++)
- for (int k = 0; k < 1000; k++)
- testFunction(k, j, i);
- System.out.println("testB time>>" + (System.nanoTime() - start));
- }
- public static void testC() {
- long start = System.nanoTime();
- int i;
- int j;
- int k;
- for (i = 0; i < 10; i++)
- for (j = 0; j < 100; j++)
- for (k = 0; k < 1000; k++)
- testFunction(k, j, i);
- System.out.println("testC time>>" + (System.nanoTime() - start));
- }
4.2 测试结果
1、测试机器配置:Pentium(R) Dual-Core CPU E5400 @2.70GHz 2.70GHz, 2GB内存;
2、循环变量i、j、k循环次数分别为10、100、1000,进行5组测试,测试结果如下:
第1组 | 第2组 | 第3组 | 第4组 | 第5组 | |
原方案 | 171846271 | 173250166 | 173910870 | 173199875 | 173725328 |
方案一 | 168839312 | 168466660 | 168372616 | 168310190 | 168041251 |
方案二 | 168001838 | 169141906 | 168230655 | 169421766 | 168240748 |
从上面的测试结果来看,优化后的方案明显性能优于原方案,达到了优化的效果。但优化方案二并没有如我们预期的优于方案一,其中第2、4、5组的数据更是比方案一差,怀疑可能是循环次数太少,以及测试环境相关因素影响下出现的结果。
3、重新调整循环变量i、j、k循环次数分别为20、200、2000,进行5组测试,测试结果如下:
第1组 | 第2组 | 第3组 | 第4组 | 第5组 | |
原方案 | 1355397203 | 1358978176 | 1358128281 | 1350193682 | 1354786598 |
方案一 | 1343482704 | 1348410388 | 1343978037 | 1347919156 | 1340697793 |
方案二 | 1342427528 | 1343897887 | 1342662462 | 1342124048 | 1336266453 |
从上面的测试结果来看,优化后的方案基本符合我们的预期结果。
5 总结
从案例分析和解决过程中的三个表的分析可知,优化方案一和优化方案二的性能都比原代码的性能好,其中优化方案二的性能是最好的。在嵌套For循环中,将循环次数多的循环放在内侧,循环次数少的循环放在外侧,其性能会提高;减少循环变量的实例化,其性能也会提高。从测试数据可知,对于两种优化方案,如果在循环次数较少的情况下,其运行效果区别不大;但在循环次数较多的情况下,其效果就比较明显了。
for循环嵌套 简单优化相关推荐
- java的for循环嵌套_优化Java的for循环嵌套的高效率方法
两个list中分别装有相同的对象数据. list1中有3万条对象数据. list2中有2万条对象数据(但是对象中的某个属性变量为空).两个list中的id或者其他变量都一模一样.请用最快的方式找出li ...
- php大数组循环嵌套的性能优化
一.前言 博主最近在用elasticsearch做项目,查出来的数据都是数组,在筛选数据组装数据的时候,难免会碰到循环嵌套的问题.如果两个50000的数组循环嵌套,那实际运算则是50000*50000 ...
- 【C语言简单说】十九:二维数组循环嵌套(2)
这节直接用循环嵌套来输出二维数组了: 注:我说的队和列并不是一般说法,我用此比喻好让新手更好理解. #include<stdio.h> #include<stdlib.h> i ...
- Java for循环嵌套for循环,你需要懂的代码性能优化技巧
前言 本篇分析的技巧点其实是比较常见的,但是最近的几次的代码评审还是发现有不少兄弟没注意到. 所以还是想拿出来说下. 正文 是个什么场景呢? 就是 for循环 里面还有 for循环, 然后做一些数据匹 ...
- Java 循环嵌套问题三:100以内质数的输出以及优化(笔试题)
质数是只有一和它本身才能被除尽的一类数,输出100以内的质数本质还是循环嵌套 首先,外层循环遍历100以内的自然数,因为1不是质数,所以从2开始,内层循环从1开始到自己本身结束,每个数都被i除一次,这 ...
- java for循环写法优化,Java优化for循环嵌套的高效率方法
前几天有人问过我一个问题,就是两个嵌套for循环执行效率的问题,问有什么好的办法替换.当时我想了想,实在想不起来,哎,惭愧!!! 请教了答案,恍然大悟. 比如:两个list中分别装有相同的对象数据. ...
- java for嵌套循环_Java优化for循环嵌套的高效率方法
前几天有人问过我一个问题,就是两个嵌套for循环执行效率的问题,问有什么好的办法替换.当时我想了想,实在想不起来,哎,惭愧!!! 请教了答案,恍然大悟. 比如:两个list中分别装有相同的对象数据. ...
- 【C语言简单说】十九:二维数组循环嵌套(1)
(▼ _ ▼) 又到了这一节 了,这是痛苦的一节,因为我完全不懂如何像新手说明循环嵌套... 因为很多新手理解不了=.=,我就直接拿我以前的教程复制上来了. 首先先说循环嵌套: 循环嵌套的意思就是循环 ...
- 代替嵌套循环java_蓝石榴_个人博客_Java中for循环嵌套的替换优化
比如:两个list中分别装有相同的对象数据,firstList中有6万条对象数据,secondList中有3万条对象数据(但是对象中的name属性变量为空).两个list中的id或者其他变量都一模一样 ...
最新文章
- 计算机应用基础模拟试题一,计算机应用基础模拟试题1
- 华一银行开发安全内部培训圆满结束
- word2vec原理_word2vec论文阅读笔记
- 使用Linux自定义自动补全命令完善自己的shell脚本
- Linux mail 邮件发送
- VINS-Mono: A Robust and Versatile Monocular Visual-Inertial State Estimator
- 理解C语言——从小菜到大神的晋级之路(1)——引言:C语言的前世今生
- 总结一下最近面试经常被问到的问题(2019年4月)
- 远程服务器返回错误 (411) 所需的长度。
- 模拟集成电路设计基础知识(一):MOS管结构及其I/V特性
- mpvue 使用wxParse解析html
- r语言 svycoxph_生存分析的Cox回归模型(比例风险模型)R语言实现及结果解读
- 分享一个Github逆天级别的彩蛋
- freeswitch实战六(呼叫转移)
- 2019滴滴java面试总结 (包含面试题解析)
- 折腾日记:树莓派如何硬盘、u盘启动 (usb boot)
- [题解]CF662D
- 从应用模式看 计算机应用经历了,触控操作堪比鼠标 Win 10平板电脑体验
- python 全栈开发,Day57(响应式页面-@media介绍,jQuery补充,移动端单位介绍,Bootstrap学习)...
- HTML的段落标记 标记P,HTML的段落标记中,标注文本以原样显示的是标记 P
热门文章
- c 语言文字输出函数,c/c++语言中文字输出函数总结
- windows7关闭计算机对话框,电脑弹出对话框很烦人怎么办?win7禁止对话框弹出的方法...
- java可以多重继承吗_Java中的多重继承与组合vs继承
- 批处理 操作mysql_超简单使用批处理(batch)操作数据库
- 安装python3.6.1_CentOS 7 安装Python3.6.1 多版本共存
- node 升级_技术周刊( Node.js 12 性能大提升 2019-04-30)
- java实现aop的几种方式_SpringAOP 的三种实现方式
- Keycloak宣布不再适配Spring Boot和Spring Security
- 如何实现Word、PDF,TXT文件的全文内容检索?
- 线下实操:搭建微服务天气预报应用!