在我的游戏中,检查了很多东西,而且索引经常超出范围,如果有时没有绘制或检查东西通常是可以的。目前我的代码很容易阅读,但在调试时,由于正在记录的异常,游戏会丢失一两帧。不过,它在 VS 之外也能正常工作。当我尝试使用大量if
语句来避免异常情况时,它大大降低了代码的可读性并消除了低 fps 损失。我想知道它是否还有其他影响。
4 回答
抛出异常是非常耗费资源的——使用 if/then 语句或其他“正常”流控制要快得多。
异常主要是昂贵的,因为生成异常实例需要执行堆栈遍历来确定异常被抛出的位置(堆栈跟踪)。它还为垃圾收集器创建了额外的负载,并且被认为是非常糟糕的设计,无法在异常情况之外使用异常。
可以使用很多
try
s 而不是更多if
s 吗?
如果您需要其中任何一个来实现功能性应用程序,那么您的设计可能有问题。异常情况通常被认为是异常的,而不是司空见惯的。
您描述的情况(索引超出范围)显然不是例外,特别是因为您忽略了例外,因为这没什么大不了的。这是一个很大的暗示,您应该首先投入精力防止异常发生。
当我试图使用大量的 if 语句来避免异常情况时......
正如您所发现的,大量if
语句不是一个好方法——它很难阅读,而且它可能会隐藏逻辑错误,这只会带来更多的麻烦。
相反,请考虑为您的对象赋予更明确定义和离散的职责,以防止它们进入可能一开始就异常的状态。如果您需要“很多很多”if
语句,那么您的对象正在检查许多条件,这意味着它们的职责可能太大了。
通常,您应该编写代码并构建逻辑,以便不使用异常来处理程序逻辑。在某些情况下,可以使用异常来处理罕见但预期的情况。但是,控制流应该避免异常,因为它们基本上goto
是可以使控制流非常混乱的语句,并且它们不是高性能的。
在您的情况下,使用异常处理逻辑错误听起来并不合适。事实上,这些例外听起来就像他们正在做他们应该做的事情。也就是说,他们告诉你你的算法是错误的。
我建议仔细查看您的代码,并确定您的代码为什么会抛出IndexOutOfBoundsException
. 如果它在您自己的参数的内部处理过程中被抛出,您可能遇到了错误或设计不佳的算法。问:“这个索引是从哪里来的?” “有没有办法编写算法,以便在设计中建立界限而不是事后才添加?”
您应该始终编写代码以避免异常。捕获它们的成本非常高。
您还应该避免大量嵌套if
语句。你是对的,它们使你的代码可读性降低。
您可能会发现switch
语句会有所帮助,但还有许多其他方法可以避免异常和if
语句。
例如,您可以编写此扩展方法:
public static class Ex
{
public static void IfBounded<T>(this T[] @this, int index, Action<T> action)
{
if (@this == null) throw new System.ArgumentNullException("@this");
if (action == null) throw new System.ArgumentNullException("action");
if (index >= @this.GetLowerBound(0) && index <= @this.GetUpperBound(0))
{
action(@this[index]);
}
}
}
现在您可以编写以下类型的代码:
var messages = new []
{
"Hello",
"Goodbye",
};
messages.IfBounded(-1, t => Console.WriteLine(t));
messages.IfBounded(0, t => Console.WriteLine(t));
messages.IfBounded(1, t => Console.WriteLine(t));
messages.IfBounded(2, t => Console.WriteLine(t));
这种特定的扩展方法可能不适合您的情况,但是这样的事情可以使您的代码非常简洁明了。