简体   繁体   English

检查异常类型性能

[英]Checking Exception Type Performance

I have a method that checks the exception passed in and returns a bool value. 我有一个检查传入的异常并返回布尔值的方法。

Currently my implementation is like this 目前我的实现是这样的

private bool ExceptionShouldNotify(Exception e)
{
    return
    e is FirstCustomException  ||
    e is SecondCustomException ||
    e is ThirdCustomException  ||
    e is FourthCustomException ||
    e is FifthCustomException  ||
    e is SixthCustomException  ||
    e is SeventhCustomException;
}

However is it better performance-wise to use a dictionary lookup rather than several OR statements and the is check? 但是它更好的性能,明智的做法是使用字典查找,而不是几个OR报表, is检查?

Something like this: 像这样:

private bool ExceptionShouldNotify(Exception e)
{
    var dict = new Dictionary<String, int> {
        { "FirstCustomException",   1 },
        { "SecondCustomException",  1 },
        { "ThirdCustomException",   1 },
        { "FourthCustomException",  1 },
        { "FifthCustomException",   1 },
        { "SixthCustomException",   1 },
        { "SeventhCustomException", 1 }
    };

    return dict.ContainsKey(e.GetType().Name);
}

Hardcoding (1st solution) is a bad practice, that's why I vote for the dictionary (2nd solution), but I suggest different implementation of the idea: 硬编码 (第一种解决方案)是一种不好的做法,这就是为什么我投票给字典( 第二种解决方案)的原因,但是我建议采用不同的想法:

   // HashSet - you don't use Value in the Dictionary, but Key
   // Type - we compare types, not their names
   private static HashSet<Type> s_ExceptionsToNotify = new HashSet<Type>() {
     typeof(FirstCustomException),
     typeof(SecondCustomException),
     ...
   };   

   // static: you don't use "this" in the method
   private static bool ExceptionShouldNotify(Exception e) {
     return s_ExceptionsToNotify.Contains(e.GetType());
   }

Having an exception caught (which include stack tracing ) you've already had a big overhead ; 捕获了一个异常(包括堆栈跟踪 ),您已经有很大的开销 ; that's why performace (7 simple comparisons versus computing a hash) is not the main issue in the context 这就是为什么性能(7个简单比较与计算哈希)不是上下文中的主要问题

It makes sense to look up the dictionary if you have considerable number of exception types to check. 如果您要检查大量异常类型,则查找字典是有意义的。 However, I would avoid using strings in this context. 但是,我将避免在这种情况下使用strings You can rely on the Type type instead: 您可以改为依赖Type类型:

var dict = new Dictionary<Type, int>()
{
    [typeof(FirstCustomerException)] = 1,
    [typeof(SecondCustomException)] = 1,
    ...
};

You can then look up the dictionary by the type of the exception object: 然后,您可以按异常对象的类型查找字典:

try
{
    ...
}
catch (Exception ex)
{
    int mapTo;
    if (dict.TryGetValue(ex.GetType(), out mapTo))
    {
        // Use mapTo value here
    }
}

You can even use the latest feature from C# 6 called exception filters to only catch those exceptions that exist in the dictionary: 您甚至可以使用C#6中称为异常过滤器的最新功能来仅捕获字典中存在的那些异常:

try
{
    ...
}
catch (Exception ex) when (dict.ContainsKey(ex.GetType())
{
    int mapTo = dict[ex.GetType()];
    // Use mapTo value here
}

This implementation is one tiny bit slower because you have to call GetType twice, and also to perform dictionary mapping two times. 此实现要慢一点,因为您必须调用两次GetType ,并且还要执行两次字典映射。 But it comes with the benefit that it guarantees that your catch block will indeed handle the exception because it will be entered only for those exceptions that are in the map and not for any other type of exception. 但是,这样做的好处是它可以保证您的catch块确实可以处理异常,因为它将仅针对映射中的那些异常输入,而不会为任何其他类型的异常输入。

Yes it should. 是的,应该。 According to the Dictionary documentation the Contains method approaches O(1) while the chain of or statements is O(N). 根据Dictionary文档Contains方法接近O(1),而链or语句是O(N)。

https://msdn.microsoft.com/en-us/library/kw5aaea4(v=vs.110).aspx#Remarks https://msdn.microsoft.com/zh-cn/library/kw5aaea4(v=vs.110).aspx#备注

If you use the Dictionary , I would change the keys to use nameof(Exception) to make it bit more save against typos. 如果您使用the Dictionary ,我将更改键以使用nameof(Exception)以使其更加省去打字错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM