最近做一个图像问题的程序,需要对一幅比较大的图进行遍历,将每个像素信息提取出来,用了BitMap及BitmapData。由于图片很大(2000*1000),每次操作都要等很久,全套操作下来居然需要12秒还多,代码优化了好多次,始终没有质的改变,今天抱着试一试的态度将循环内的对象属性访问全部提取到循环外,速度居然一下就上去了,表达能力有限,这里直接看代码:
没有优化
public void Binary()
{
for (int j = 0; j < originalImage.Height; j++)
{
for (int i = 0; i < originalImage.Width; i++)
{
brightness = imageBrightness[i + j * originalImage.Width];
if (brightness < 128)
{
binaryImageData[i + j * originalImage.Width] = 1;
}
else
{
binaryImageData[i + j * originalImage.Width] = 0;
}
}
}
}
上面的代码中,循环内每次都要访问originalImage.Width等对象属性,现在将其提到循环外
优化过的代码
public void Binary()
{
int h = originalImage.Height;
int w = originalImage.Width;
for (int j = 0; j < h; j++)
{
for (int i = 0; i < w; i++)
{
brightness = imageBrightness[i + j * w];
if (brightness < 128)
{
binaryImageData[i + j * w] = 1;
}
else
{
binaryImageData[i + j * w] = 0;
}
}
}
}
就是在循环外用一个简单变量代替对象的属性,经过测试,我的程序在优化过后速度居然提高了20多倍,遍历3000*2000的图从接近40秒降到了1500毫秒,效果显著。
简单分析,访问属性效率不高可能有两个原因
1.属性内部在get时要有其他运算,占用时间
2.取一个对象的属性,要对对象定位(不知道怎么形容,可能叫做寻址更准确),经过循环的累加效应,这部分时间越来越多。
以上只是个人猜测,欢迎大家帮我分析出准确原因