对于已知情况,应该避免尝试捕获 [英] Should try-catch be avoided for known cases

查看:118
本文介绍了对于已知情况,应该避免尝试捕获的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个案件,我知道会发生,但非常稀缺。例如,每运行一万次代码,这可能会发生一次。

I have a case which I know will happen but very scarce. For example in every 10 thousand times the code runs, this might happen once.

我可以通过一个简单的检查这种情况,如果但是这个如果会多次运行而没有用。

I can check for this case by a simple if but this if will run many times with no use.

另一方面我可以放置try-catch块中的代码,当发生特殊情况时,我会做恢复所需的事情。

On the other hand I can place the code in try-catch block and when that special case happens I do what is needed to recover.

问题是哪一个更好?我知道一般来说,try-catch不应该用于已知的情况,因为开销问题以及应用程序逻辑不应该依赖catch代码,但运行if多次会有更多的性能问题。我使用这个小测试代码对此进行了测试:

The question is which one is better? I know that generally speaking try-catch should not be used for known cases because of the overhead issue and also the application logic should not rely on catch code, but running an if multiple times will have more performance issue. I have tested this using this small test code:

static void Main(string[] args)
{
    Stopwatch sc = new Stopwatch();
    var list = new List<int>();
    var rnd = new Random();
    for (int i = 0; i < 100000000; i++)
    {
        list.Add(rnd.Next());
    }

    sc.Start();
    DoWithIf(list);
    sc.Stop();
    Console.WriteLine($"Done with IFs in {sc.ElapsedMilliseconds} milliseconds");
    sc.Restart();
    DoWithTryCatch(list);
    sc.Stop();
    Console.WriteLine($"Done with TRY-CATCH in {sc.ElapsedMilliseconds} milliseconds");
    Console.ReadKey();
}

private static int[] DoWithTryCatch(List<int> list)
{
    var res = new int[list.Count ];
    try
    {
        for (int i = 0; i < list.Count; i++)
        {
            res[i] = list[i];
        }
        return res;
    }
    catch
    {
        return res;
    }
}

private static int[] DoWithIf(List<int> list)
{
    var res = new int[list.Count - 1];
    for (int i = 0; i < list.Count; i++)
    {
        if (i < res.Length)
            res[i] = list[i];
    }
    return res;
}

此代码只是将大量数字复制到数量不足的数组中。在我的机器中检查数组边界每次需要 210毫秒来运行,同时使用try-catch,一旦在 190毫秒中运行,它将会命中catch。

This code simply copies a lot of numbers to an array with not enough size. In my machine checking array bounds each time takes around 210 milliseconds to run while using try-catch that will hit catch once runs in around 190 milliseconds.

另外,如果您认为这取决于我的情况,我会在应用程序中获得推送通知,并检查我是否有该消息的主题。如果不是,我将获取并存储下一条消息的主题信息。在很少的主题中有很多消息。

Also if you think it depends on the case my case is that I get push notifications in an app and will check if I have the topic of the message. If not I will get and store the topic information for next messages. There are many messages in few topics.

推荐答案

在你的情况下,你已经错过了明显的优化:如果你担心调用一个如果 100.000次太多了......

In your case, you have somehow missed the obvious optimization: if you worry that calling an if 100.000 times is too much... don't?

private static int[] DoWithIf(List<int> list)
{
    var res = new int[list.Count - 1];

    var bounds = Math.Min(res.Length, list.Count)

    for (int i = 0; i < bounds; i++)
    {        
        res[i] = list[i];
    }
    return res;
}

所以我知道这只是一个测试用例,但答案是:优化如果你需要它,你需要它。如果你在循环中有某些东西应该是昂贵的,那么试着把它移出循环。 基于逻辑优化,而不是基于编译器结构。如果您要优化编译器结构,那么无论如何都不应该使用托管和/或高级语言进行编码。

So I know this is only a test case, but the answer is: optimize if you need it and for what you need it. If you have something in a loop that's supposedly costly, then try to move it out of the loop. Optimize based on logic, not based on compiler constructs. If you are down to optimizing compiler constructs, you should not be coding in a managed and/or high level language anyway.

这篇关于对于已知情况,应该避免尝试捕获的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆