我们正在使用 EmguCV 开发视频处理应用程序,最近不得不进行一些像素级操作。我最初编写的循环遍历图像中的所有像素,如下所示:
for (int j = 0; j < Img.Width; j++ )
{
for (int i = 0; i < Img.Height; i++)
{
// Pixel operation code
}
}
执行循环的时间非常糟糕。然后我在 EmguCV 论坛上发帖,得到了这样切换循环的建议:
for (int j = Img.Width; j-- > 0; )
{
for (int i = Img.Height; i-- > 0; )
{
// Pixel operation code
}
}
我很惊讶地发现代码执行了一半的时间!
我唯一能想到的是每次访问属性时在循环中进行的比较,它不再需要这样做。这是加速的原因吗?还是有别的东西?我很高兴看到这种改进。如果有人能澄清原因,我会很高兴。
最佳答案
区别不在于分支的成本,而是您在内循环中获取对象属性 Img.Width
和 Img.Height
的事实。优化器无法知道这些是用于该循环目的的常量。
您应该通过这样做获得相同的性能加速。
const int Width = Img.Width;
const int Height = Img.Height;
for (int j = 0; j < Width; j++ )
{
for (int i = 0; i < Height; i++)
{
// Pixel operation code
}
}
编辑:
正如 Joshua 建议的那样,将 Width 放在内部循环中将使您按顺序遍历内存,这将提高缓存一致性,并且可能会更快。 (取决于您的位图有多大)。
const int Width = Img.Width;
const int Height = Img.Height;
for (int i = 0; i < Height; i++)
{
for (int j = 0; j < Width; j++ )
{
// Pixel operation code
}
}
关于c# - C# 中的循环反转加速应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2384650/