试试{} Catch优化?

时间:2014-06-23 12:40:34

标签: c# algorithm optimization try-catch game-engine

我对有关例外的最佳做法有疑问。本周末,我正在研究我的小游戏,我发现自己想知道是否最好使用IF或TRY来验证NULL ...以下是同一功能的两个变体:

这是我使用IF的代码

//Using IF
void ParseGamePad() {
    GamePadData pad = GamePad.GetDate(0);
    foreach(var btn in Enum.GetValues(GamePad.BUTTONS)) {
        if(myArray.ContainsKey(btn))
            if(myArray[btn]!=null)
                myArray[btn](); //Execute function reference in array
    }
    return;
}

以下是使用Try{}Catch

的代码
//Using TRY
void ParseGamePad() {
    GamePadData pad = GamePad.GetDate(0);
    foreach(var btn in Enum.GetValues(GamePad.BUTTONS)) {
        try {
            myArray[btn](); //Execute function reference in array
        } catch(System.Exception e) {
            // Nothing to do here
        }
    }
    return;
}

我的方法是,当数组中不存在该元素时,IF块比TRY块更快,而当元素存在时,TRY更快,但在捕获异常时速度较慢。

你们会做什么?

PS:这个项目是在嵌入式系统上,因此CPU和RAM是一个因素。

4 个答案:

答案 0 :(得分:5)

不要对程序流使用异常 - 它们用于捕获异常情况。如果myArray[btn] 永远不应该为空,那么当它 时抛出异常会没问题,但抓住它以查看它是否为空并不是最佳做法(另外,捕获Exception将涵盖很多的可能条件,而不仅仅是当值为null或未找到时。

就性能而言,检查一个对象的null应该非常便宜,所以我不希望在正常情况下有任何明显的性能差异。

使用TryGetValue可以将索引查找的数量减少两个(可以显着提升性能):

foreach(var btn in Enum.GetValues(GamePad.BUTTONS)) {
    Action<Button> func;   // Guessing on the type here
    bool found = myArray.TryGetValue(btn, out func);
    if(found && func != null)
        func(); //Execute function reference in array
}

答案 1 :(得分:2)

您不应该依赖Exceptions作为系统的正确流程,因为它们会产生性能影响。由于null检查是一个chearp异常,可能会传播调用链(可能需要一段时间,具体取决于您的堆栈深度),您应该使用无效检查。

我还要说Exceptions应该保留意外行为。您可能会认为持有空值的Dictionary是您程序中的异常行为,这很好,因为它是基于意见的。我肯定会反对它。

您应该继续检查How expensive are exceptions in C#?,了解有关异常和效果的出色链接。

答案 2 :(得分:2)

如果我怀疑myArray是一个词典,你可以使用TryGetValue。

在这种情况下捕获异常不是一个好的解决方案。

第一个选项有一个(非常)轻微的问题,因为你要两次查找该项目,所以我会使用TryGetValue。 (如果myArray是一个词典,那么myArray就不是一个好名字。)

答案 3 :(得分:1)

至少,我不会抓住Exception,而是更特殊的异常类型。