C#性能异常成本

时间:2017-06-12 09:31:16

标签: c# performance dictionary exception

我正在构建一个项目,其中配置文件将作为字典加载。为了防止无效配置,我只是添加了一个try catch框架。但我注意到,当异常抛出时,会有一个戏剧性的性能下降。所以我做了一个测试:

var temp = new Dictionary<string, string> {["hello"] = "world"};
var tempj = new JObject() {["hello"]="world"};
Stopwatch sw = new Stopwatch();
sw.Start();
for (int i = 0; i < 100; i++)
{
     try
     {
        var value = temp["error"];
     }
     catch
     {
          // ignored
     }
}
sw.Stop();
Console.WriteLine("Time cost on Exception:"+sw.ElapsedMilliseconds +"ms");
sw.Restart();
for (int i = 0; i < 100; i++)
{
   var value = tempj["error"];   //equivalent to value=null
}
Console.WriteLine("Time cost without Exception:" + sw.ElapsedMilliseconds + "ms");
Console.ReadLine();

结果是:

  

例外的时间成本:1789毫秒

     

没有例外的时间成本:0毫秒

这里的 JObject 取自 Newtownsoft.Json ,当没有找到密钥时,它不会抛出异常,而 Dictionary

所以我的问题是:

  1. 异常抛出真的会减慢程序的速度吗?
  2. 如果可能发生多处异常,我如何保证性能?
  3. 无论如何,如果我真的想在这种情况下使用 Dictionary 吗?(关闭KeyNotFoundException?)
  4. 谢谢!

1 个答案:

答案 0 :(得分:0)

使用Dictionary.TryGetValue来避免示例代码中的异常。最昂贵的部分是try .. catch

如果您无法摆脱异常,那么您应该使用不同的模式在循环内执行操作。

而不是

for ( i = 0; i < 100; i++ )
    try
    {
        DoSomethingThatMaybeThrowException();
    }
    catch (Exception)
    {
        // igrnore or handle
    }

,无论是否引发异常,都会为每一步设置try .. catch,使用

int i = 0;
while ( i < 100 )
    try
    {
        while( i < 100 )
        {
            DoSomethingThatMaybeThrowException();
            i++;
        }
    }
    catch ( Exception )
    {
        // ignore or handle
        i++;
    }

只会在抛出异常时设置新的try .. catch

<强>顺便说一句

我无法像您描述的那样重现代码的大幅减速。 .net fiddle