C#:优化循环内的条件
C#: Optimize conditional within a loop
我有以下嵌套循环:
(...)
while (some_condition)
{
(...)
MyObject p = new MyObject(i, j);
for (int r = -1; r <= 1; r++)
{
for (int c = -1; c <= 1; c++)
{
// check matrix bounds
if (p.y + r <= 0 || p.y + r >= bound1 ||
p.x + c <= 0 || p.x + c >= bound2)
{
continue;
}
else if (matrix[p.y + r][p.x + c]=='$') // at this point no IndexOutOfBounds may be raised as it is checked in previous condition
{
continue;
}
AddItem(r, c);
}
}
}
MyObject 是一个 class,具有以下属性:
public class MyObject {
public int x;
public int y;
public MyObject(int x, int y)
{
this.x = x;
this.y = y;
}
// Other methods ....
}
所以我担心性能,我的意思是,我不喜欢循环内的条件,因为性能可能会降低,那么我该如何优化呢?
另外我想让代码更易读所以我重写了如下:
while (some_condition)
{
(...)
MyObject p = new MyObject(i, j);
for (int r = -1; r <= 1; r++)
{
for (int c = -1; c <= 1; c++)
{
if (!IsOutOfBounds(r, c, p) && !IsDollar(r, c, p))
{
AddItem(r, c);
}
}
}
}
private bool IsOutOfBounds(int r, int c, MyObject p)
{
return (p.y + r <= 0 || p.y + r >= bound1 ||
p.x + c <= 0 || p.x + c >= bound2);
}
private bool IsDollar(int r, int c, MyObject p)
{
// matrix is global
return (matrix[p.y + r][p.x + c]=='$');
}
但是现在,在循环内调用函数也会降低性能,那么内联函数怎么办呢?我是否必须在两个函数之前使用 [MethodImpl(MethodImplOptions.AggressiveInlining)] 属性?
方法调用和 if 语句不会对您的性能造成太大影响,除非您每秒调用该方法 1000 次,或者您使用的是一台非常旧的机器,但编译器也会进一步优化它。因此,如果您的程序 运行 很慢,您应该更多地关注使这样的代码更具可读性并寻找真正的瓶颈。
但我也有一个关于你的代码的问题,你似乎永远不会在你的循环中改变 x 和 y,所以你不能把越界和美元检查带到你的循环之外。
干得好,使它更具可读性并正确命名了方法。由于 for
循环仅执行 3 次,对于值 -1、0 和 1,性能并没有像您所拥有的那样少的循环迭代真正发挥作用。
代码可读性优于每次过早和不必要的优化。
我有以下嵌套循环:
(...)
while (some_condition)
{
(...)
MyObject p = new MyObject(i, j);
for (int r = -1; r <= 1; r++)
{
for (int c = -1; c <= 1; c++)
{
// check matrix bounds
if (p.y + r <= 0 || p.y + r >= bound1 ||
p.x + c <= 0 || p.x + c >= bound2)
{
continue;
}
else if (matrix[p.y + r][p.x + c]=='$') // at this point no IndexOutOfBounds may be raised as it is checked in previous condition
{
continue;
}
AddItem(r, c);
}
}
}
MyObject 是一个 class,具有以下属性:
public class MyObject {
public int x;
public int y;
public MyObject(int x, int y)
{
this.x = x;
this.y = y;
}
// Other methods ....
}
所以我担心性能,我的意思是,我不喜欢循环内的条件,因为性能可能会降低,那么我该如何优化呢?
另外我想让代码更易读所以我重写了如下:
while (some_condition)
{
(...)
MyObject p = new MyObject(i, j);
for (int r = -1; r <= 1; r++)
{
for (int c = -1; c <= 1; c++)
{
if (!IsOutOfBounds(r, c, p) && !IsDollar(r, c, p))
{
AddItem(r, c);
}
}
}
}
private bool IsOutOfBounds(int r, int c, MyObject p)
{
return (p.y + r <= 0 || p.y + r >= bound1 ||
p.x + c <= 0 || p.x + c >= bound2);
}
private bool IsDollar(int r, int c, MyObject p)
{
// matrix is global
return (matrix[p.y + r][p.x + c]=='$');
}
但是现在,在循环内调用函数也会降低性能,那么内联函数怎么办呢?我是否必须在两个函数之前使用 [MethodImpl(MethodImplOptions.AggressiveInlining)] 属性?
方法调用和 if 语句不会对您的性能造成太大影响,除非您每秒调用该方法 1000 次,或者您使用的是一台非常旧的机器,但编译器也会进一步优化它。因此,如果您的程序 运行 很慢,您应该更多地关注使这样的代码更具可读性并寻找真正的瓶颈。
但我也有一个关于你的代码的问题,你似乎永远不会在你的循环中改变 x 和 y,所以你不能把越界和美元检查带到你的循环之外。
干得好,使它更具可读性并正确命名了方法。由于 for
循环仅执行 3 次,对于值 -1、0 和 1,性能并没有像您所拥有的那样少的循环迭代真正发挥作用。
代码可读性优于每次过早和不必要的优化。