原文:http://blog.csdn.net/swimmy_gy/article/details/50953131

1 案例描述

某日,在JavaEye上看到一道面试题,题目是这样的:请对以下的代码进行优化

Java代码  
  1. for (int i = 0; i < 1000; i++)
  2. for (int j = 0; j < 100; j++)
  3. for (int k = 0; k < 10; k++)
  4. 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 优化方案一 
代码如下:

Java代码  
  1. for (int i = 0; i < 10; i++)
  2. for (int j = 0; j < 100; j++)
  3. for (int k = 0; k < 1000; k++)
  4. 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 优化方案二 
代码如下:

Java代码  
  1. int i, j, k;
  2. for (i = 0; i < 10; i++)
  3. for (j = 0; j < 100; j++)
  4. for (k = 0; k < 1000; k++)
  5. 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 测试代码

Java代码  
  1. public static void testFunction(int i, int j, int k) {
  2. System.out.print("");   // 注:该方法不影响整体优化,这里只有简单输出
  3. }
  4. public static void testA() {
  5. long start = System.nanoTime();
  6. for (int i = 0; i < 1000; i++)
  7. for (int j = 0; j < 100; j++)
  8. for (int k = 0; k < 10; k++)
  9. testFunction(i, j, k);
  10. System.out.println("testA time>>" + (System.nanoTime() - start));
  11. }
  12. public static void testB() {
  13. long start = System.nanoTime();
  14. for (int i = 0; i < 10; i++)
  15. for (int j = 0; j < 100; j++)
  16. for (int k = 0; k < 1000; k++)
  17. testFunction(k, j, i);
  18. System.out.println("testB time>>" + (System.nanoTime() - start));
  19. }
  20. public static void testC() {
  21. long start = System.nanoTime();
  22. int i;
  23. int j;
  24. int k;
  25. for (i = 0; i < 10; i++)
  26. for (j = 0; j < 100; j++)
  27. for (k = 0; k < 1000; k++)
  28. testFunction(k, j, i);
  29. System.out.println("testC time>>" + (System.nanoTime() - start));
  30. }

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循环嵌套 简单优化相关推荐

  1. java的for循环嵌套_优化Java的for循环嵌套的高效率方法

    两个list中分别装有相同的对象数据. list1中有3万条对象数据. list2中有2万条对象数据(但是对象中的某个属性变量为空).两个list中的id或者其他变量都一模一样.请用最快的方式找出li ...

  2. php大数组循环嵌套的性能优化

    一.前言 博主最近在用elasticsearch做项目,查出来的数据都是数组,在筛选数据组装数据的时候,难免会碰到循环嵌套的问题.如果两个50000的数组循环嵌套,那实际运算则是50000*50000 ...

  3. 【C语言简单说】十九:二维数组循环嵌套(2)

    这节直接用循环嵌套来输出二维数组了: 注:我说的队和列并不是一般说法,我用此比喻好让新手更好理解. #include<stdio.h> #include<stdlib.h> i ...

  4. Java for循环嵌套for循环,你需要懂的代码性能优化技巧

    前言 本篇分析的技巧点其实是比较常见的,但是最近的几次的代码评审还是发现有不少兄弟没注意到. 所以还是想拿出来说下. 正文 是个什么场景呢? 就是 for循环 里面还有 for循环, 然后做一些数据匹 ...

  5. Java 循环嵌套问题三:100以内质数的输出以及优化(笔试题)

    质数是只有一和它本身才能被除尽的一类数,输出100以内的质数本质还是循环嵌套 首先,外层循环遍历100以内的自然数,因为1不是质数,所以从2开始,内层循环从1开始到自己本身结束,每个数都被i除一次,这 ...

  6. java for循环写法优化,Java优化for循环嵌套的高效率方法

    前几天有人问过我一个问题,就是两个嵌套for循环执行效率的问题,问有什么好的办法替换.当时我想了想,实在想不起来,哎,惭愧!!! 请教了答案,恍然大悟. 比如:两个list中分别装有相同的对象数据. ...

  7. java for嵌套循环_Java优化for循环嵌套的高效率方法

    前几天有人问过我一个问题,就是两个嵌套for循环执行效率的问题,问有什么好的办法替换.当时我想了想,实在想不起来,哎,惭愧!!! 请教了答案,恍然大悟. 比如:两个list中分别装有相同的对象数据. ...

  8. 【C语言简单说】十九:二维数组循环嵌套(1)

    (▼ _ ▼) 又到了这一节 了,这是痛苦的一节,因为我完全不懂如何像新手说明循环嵌套... 因为很多新手理解不了=.=,我就直接拿我以前的教程复制上来了. 首先先说循环嵌套: 循环嵌套的意思就是循环 ...

  9. 代替嵌套循环java_蓝石榴_个人博客_Java中for循环嵌套的替换优化

    比如:两个list中分别装有相同的对象数据,firstList中有6万条对象数据,secondList中有3万条对象数据(但是对象中的name属性变量为空).两个list中的id或者其他变量都一模一样 ...

最新文章

  1. 计算机应用基础模拟试题一,计算机应用基础模拟试题1
  2. 华一银行开发安全内部培训圆满结束
  3. word2vec原理_word2vec论文阅读笔记
  4. 使用Linux自定义自动补全命令完善自己的shell脚本
  5. Linux mail 邮件发送
  6. VINS-Mono: A Robust and Versatile Monocular Visual-Inertial State Estimator
  7. 理解C语言——从小菜到大神的晋级之路(1)——引言:C语言的前世今生
  8. 总结一下最近面试经常被问到的问题(2019年4月)
  9. 远程服务器返回错误 (411) 所需的长度。
  10. 模拟集成电路设计基础知识(一):MOS管结构及其I/V特性
  11. mpvue 使用wxParse解析html
  12. r语言 svycoxph_生存分析的Cox回归模型(比例风险模型)R语言实现及结果解读
  13. 分享一个Github逆天级别的彩蛋
  14. freeswitch实战六(呼叫转移)
  15. 2019滴滴java面试总结 (包含面试题解析)
  16. 折腾日记:树莓派如何硬盘、u盘启动 (usb boot)
  17. [题解]CF662D
  18. 从应用模式看 计算机应用经历了,触控操作堪比鼠标 Win 10平板电脑体验
  19. python 全栈开发,Day57(响应式页面-@media介绍,jQuery补充,移动端单位介绍,Bootstrap学习)...
  20. HTML的段落标记 标记P,HTML的段落标记中,标注文本以原样显示的是标记 P

热门文章

  1. c 语言文字输出函数,c/c++语言中文字输出函数总结
  2. windows7关闭计算机对话框,电脑弹出对话框很烦人怎么办?win7禁止对话框弹出的方法...
  3. java可以多重继承吗_Java中的多重继承与组合vs继承
  4. 批处理 操作mysql_超简单使用批处理(batch)操作数据库
  5. 安装python3.6.1_CentOS 7 安装Python3.6.1 多版本共存
  6. node 升级_技术周刊( Node.js 12 性能大提升 2019-04-30)
  7. java实现aop的几种方式_SpringAOP 的三种实现方式
  8. Keycloak宣布不再适配Spring Boot和Spring Security
  9. 如何实现Word、PDF,TXT文件的全文内容检索?
  10. 线下实操:搭建微服务天气预报应用!