{}查明优化

本文关键字:优化 | 更新日期: 2023-09-27 18:09:48

我有一个关于例外的最佳实践的问题。这个周末,我正在制作我的小游戏,我发现自己想知道是否最好使用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是一个因素。

{}查明优化

不要在程序流中使用异常——它们是用来捕获异常情况的。如果myArray[btn] 不应该为null,那么当它时抛出异常是可以的,但是捕获它以查看它是否为null并不是最佳实践(另外,捕获Exception将涵盖许多可能的条件,而不仅仅是当值为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
}

如果myArray是一个Dictionary,你可以使用TryGetValue。

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

第一个选项有一个(非常)小的问题,因为您要查找项目两次,所以我将使用TryGetValue。(如果myArray是一个Dictionary,那么myArray不是一个好名字)

您不应该依赖Exceptions作为系统的适当流,因为它们会对性能产生影响。由于null检查是一种廉价的异常,它可能会在调用链上传播(这可能需要一段时间,这取决于您的堆栈深度),因此您应该使用null检查。

我还会说Exceptions应该保留用于意外行为。您可能会认为Dictionary持有null值是程序中的异常行为,这很好,因为它是基于意见的。我绝对不建议这样做。

你应该继续检查c#中的异常有多昂贵?

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