求助!!!提高for循环速度
我的程序由于for循环过多而导致速度很慢,求高手帮忙优化啊!
原代码比较复杂,我已经将其简化如下:
int width = 8000;
int cell[4][4], p[4][8000];//p中各个元素的值或为0或为1
int i, j, r = 2;
for(i=0; i<(4+1)/2; i++)
{
for(j=i; j<(4+1)/2; j++)
{
if ( ((i-r)*(i-r)+(j-r)*(j-r)) < (r+0.5)*(r+0.5) )
{
cell[i][j]= 1;
cell[i][4-1-j] = 1;
cell[j][i]= 1;
cell[j][4-1-i] = 1;
cell[4-1-i][j] = 1;
cell[4-1-i][4-1-j] = 1;
cell[4-1-j][i] = 1;
cell[4-1-j][4-1-i] = 1;
}
}
}
int n = 0;
for(int k = 0; k < 8000; k++)
{
n = 0;
for(i = 0; i < 4; i++)
for(j = 0; j < 4; j++)
{
if(cell[i][j] != 0 && p[i][k] != 0)
n++;
}
//后面还有类似的for循环,且会对cell的值做修改
}
性能优化
[解决办法]
1、用一维数组代替二维数组;
2、(i-r)*(i-r)+(j-r)*(j-r))<(r+0.5)*(r+0.5)这个关于(i,j)的条件可以直接建表,不要每次都去计算。
[解决办法]
貌似可以转化成整型运算,提高点速度。
if ( ((i-r)*(i-r)+(j-r)*(j-r)) < (r+0.5)*(r+0.5) )
[解决办法]
如果不能改算法,就将能够提前算出的表达式用变量代替,并放到循环外。
[解决办法]
(i-r)*(i-r)+(j-r)*(j-r)) < (r+0.5)*(r+0.5)
------------------------------------
上面好多的童鞋看题不仔细,这不是关键啊,这个才循环几次,不影响的。
下面那个8000次的循环里面再2重循环才是问题所在。
我觉得从优化循环来说,不一定能提升多少的效率。
看起来似乎是大规模的矩阵运算,要从数学这方面入手,改进算法。
[解决办法]
把条件判断中if(cell[i][j] != 0 && p[i][k] != 0)一部分提到前面,可以减少内层循环的次数:
for(int k = 0; k < 8000; k++)
{
n = 0;
for(i = 0; i < 4; i++)
if( p[i][k] != 0)//先判断一下p[i][k],不符合条件就不进行内层循环
{
for(j = 0; j < 4; j++)
{
if(cell[i][j] != 0)
n++;
}
}
//后面还有类似的for循环,且会对cell的值做修改
}
int n_values[8000] = {0};
for(i = 0; i < 4; i++)
for(j = 0; j < 4; j++)
{
if(cell[i][j] != 0)
for(int k = 0; k < 8000; k++)
{
if(p[i][k+j] != 0)
n_values[k]++;
}
}
int cell[4][4], p[4][8000];//p中各个元素的值或为0或为1
for(int k = 0; k < 8000; k++)
{
n = 0;
for(i = 0; i < 4; i++)
for(j = 0; j < 4; j++)
{
if(cell[i][j] != 0 && p[i][k] != 0)
/*
1.上面提到了p里面的元素都是0或者1,如此的话,可不可以不要用int型,用单字节的char型甚至一个bit来表示?
2.不等于操作是否可以用与操作来进行比较?
3.想了想可能还是数据结构的问题。如果cell[4][4]中的元素也是0或者1,那么cell数组是不需要的,用一个short型变量(刚好是16个bit)就足够了。
然后你的p变量当然也可以简化,简化完了之后做与操作就可以了。
*/
n++;
}
for(i=0; i<(4+1)/2; i++)
{
for(j=i; j<(4+1)/2; j++)
{
if ( ((i-r)*(i-r)+(j-r)*(j-r)) < (r+0.5)*(r+0.5) )
{
cell[i][j] = 1;
cell[i][4-1-j] = 1;
cell[j][i] = 1;
cell[j][4-1-i] = 1;
cell[4-1-i][j] = 1;
cell[4-1-i][4-1-j] = 1;
cell[4-1-j][i] = 1;
cell[4-1-j][4-1-i] = 1;
}
}
}
for(int k = 0; k < 8000; k++)
{
n = 0;
for(i = 0; i < 4; i++)
for(j = 0; j < 4; j++)
{
if(cell[i][j] != 0 && p[i][k] != 0)
n++;
}
}
count = 0;
for(int i = 0; k < 4; i++)
{
m=0;
n=0;
for(k = 0; k < 4; k++){
if( p[i][k] != 0)
m++;
}
for(j = 0; j < 4; j++)
{
if(cell[i][j] != 0 )
n++;
count += m*n;
}
int cell[4][4], p[4][8000], cellToByte[4], src[4][1000], res[4][1000];
int tmp = 0;
for (int i = 0; i < 4; ++i)
{
for (int j = 0; j < 1000; ++j)
{
tmp = 0;
for (int m = 0; m < 8; ++m)
{
tmp = tmp << 4;
if (p[i][j * 8 + m] != 0)
tmp += 15;// 1111B
}
res[i][j] = tmp;
}
}
for (int i = 0; i < 4; ++i)
{
tmp = 0;
for (int j = 0; j < 4; ++j)
{
tmp = tmp << 1;
if (cell[i][j] != 0)
tmp += 1;
}
cellToByte[i] = 0;
for (int m = 0; m < 8; ++m)
{
cellToByte[i] = cellToByte[i] << 4;
cellToByte[i] += tmp;
}
}
for (int i = 0; i < 1000; ++i)
{
for (int j = 0; j < 4; ++j)
res[j][i] = cellToByte[j] & src[j][i];
}
22 for(int k = 0; k < 8000; k++)
23 {
24 n = 0;
25 for(j = 0; j < 4; j++)
26 {
27 if(cell[0][j] != 0 && p[0][k] != 0)
28 n++;
29 }
30 for(j = 0; j < 4; j++)
31 {
32 if(cell[1][j] != 0 && p[1][k] != 0)
33 n++;
34 }
35 for(j = 0; j < 4; j++)
36 {
37 if(cell[2][j] != 0 && p[3][k] != 0)
38 n++;
39 }
40 for(j = 0; j < 4; j++)
41 {
42 if(cell[3][j] != 0 && p[3][k] != 0)
43 n++;
44 }
45 }
int n = 0;
for(int k = 0; k < 8000; k++)
{
n = 0;//A)这个有用吗
for(i = 0; i < 4; i++)
for(j = 0; j < 4; j++)
{
if(cell[i][j] != 0 && p[i][k] != 0)
n++;
}
//后面还有类似的for循环,且会对cell的值做修改
}
int n = 0;
for(i = 0; i < 4; i++)//短的循环放在外面,
for(j = 0; j < 4; j++)//
if(cell[i][j]) //公共操作从循环内提出到循环外部,这是循环优化的一种方法
for(int k = 0; k < 8000; k++)//长的循环放在内部,这是循环优化的另一种方法,
//不知道是否所有编译器都自动这样做
{
if(p[i][k])n++;//有跳转
//或如果p[i][k]只是0或1; n+= p[i][k];无跳转,
}
//后面还有类似的for循环,且会对cell的值做修改
}
int n = 0;
for(int k = 0; k < 8000; k++)
{
n = 0;//A)这个有用吗,如果有用的话,下面这样做:
for(i = 0; i < 4; i++)
if(p[i][k])//公共操作从循环内提出到循环外部,这是循环优化的一种方法
for(j = 0; j < 4; j++){
if(cell[i][j] )n++;//可以改为 n+=cell[i][j];如果cell[i][j只有0,1两个值
//直接计算可能比比较后计算快,因为不存在跳转,程序可以直接执行
//会打乱流水线。
}
//后面还有类似的for循环,且会对cell的值做修改
}