博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
嵌套循环的效率优化
阅读量:6551 次
发布时间:2019-06-24

本文共 2084 字,大约阅读时间需要 6 分钟。

  hot3.png

日常开发中,我们经常会遇到类似这样的嵌套循环:

for (int i = 0; i < outterLoopCount; i++)     for (int j = 0; j < innerLoopCount; j++)	 doSomething();

 

一般的说法是把循环次数少的循环放在外面,如jdk里java.util.Collections.disjoint(Collection<?> c1, Collection<?> c2)的实现.

public static boolean disjoint(Collection
c1, Collection
c2) { /* * We're going to iterate through c1 and test for inclusion in c2. * If c1 is a Set and c2 isn't, swap the collections. Otherwise, * place the shorter collection in c1. Hopefully this heuristic * will minimize the cost of the operation. */ if ((c1 instanceof Set) && !(c2 instanceof Set) || (c1.size() > c2.size())) { Collection
tmp = c1; c1 = c2; c2 = tmp; } for (Object e : c1) if (c2.contains(e)) return false; return true; }

 

这种方法是出于减少循环次数的目的,能减少  (大循环长度 - 小循环长度)次循环,但这样能保证效率总是最优吗?

static void loop() {		int[][] arr = new int[1000000][10];		// 第一个循环,大循环放在里面		long start = System.currentTimeMillis();		for (int i = 0; i < 10; i++)			for (int j = 0; j < 1000000; j++)				arr[j][i] = i + j;		long loop1End = System.currentTimeMillis();		// 第二个循环,大循环放在外面		for (int i = 0; i < 1000000; i++)			for (int j = 0; j < 10; j++)				arr[i][j] = i + j;		long loop2End = System.currentTimeMillis();		System.out.println(loop1End - start);		System.out.println(loop2End - loop1End);	}

 

在我的机器上运行,第二个循环总是比第一个循环快。

所以将循环次数少的循环放在外面只考虑到了循环次数,并没有考虑到单次循环花费的时间,并不总是正确的优化方法。
那么怎样才对正确的优化循环呢?我首先想到的是对其建立模型求解。

有两个循环loop1, loop2,次数为分别为 x,y ,单次循环时间分别为 a,b;

设x > y >= 0;
a >= 0;
b >= 0;
解:
设 n = x - y, 则 n >0 且为常数,  y = x - n;

两种组合花费的时间分别为:

loop1 在外,loop2 在内:  x(a + b * y)    #1式

loop1 在内,loop2 在外:y(b + a * x)    #2式

时间差t为:

t =  #1 - #2t  =  (b - a) x^2 + (n + 1)(a - b)x + bn

(1) 当a==b时,t是常量bn;

(2) 当a<>b时,是一个二次函数,根据我们设置的条件,不能得到惟一的函数图形。

其顶点为: ((n + 1) / 2 , (a -b)(n + 1) ^ 2 / 4);

落在t轴上的坐标为: (0, bn);

落在x轴上的坐标为: 1/2的 (n + 1) ^ 2 + 4bn / (a - b) 平方根 - (n + 1);

说到最后,依然无法得出指导性的优化原则,当然了一般编程时并不需要去考虑这种问题,对代码效率影响太小了,并没有什么太多的实际意义。

转载于:https://my.oschina.net/coda/blog/35672

你可能感兴趣的文章
Python 多线程,文件io
查看>>
我的友情链接
查看>>
我的友情链接
查看>>
网站SEO流量下降可分析以下原因
查看>>
mysql datestamp坑
查看>>
Office 365中管理员角色介绍-初级篇
查看>>
域用户密码策略注意事项
查看>>
imagick
查看>>
手动清除explorer.exe病毒
查看>>
Linux 5 开机出现grub.conf不能启动解决
查看>>
《三年零六个月山歌其五.枫叶》
查看>>
office2003和2007共存时,如何默认使用2003?
查看>>
PHP发布webService和调用webService
查看>>
硬盘根目录里的Msdia80.dll文件
查看>>
cocos2d-x学习笔记-plist动画
查看>>
由想实现webview的flash跳转引发的优酷视频地址解析问题
查看>>
SEP迁移升级方案
查看>>
我的友情链接
查看>>
我的友情链接
查看>>
负载均衡集群解决方案 (一)LVS-DR
查看>>