【问题标题】:C# performance cost of exceptions [duplicate]异常的C#性能成本[重复]
【发布时间】:2017-06-12 09:31:15
【问题描述】:

我正在构建一个项目,其中配置文件将作为字典加载。为了防止无效配置,我只是添加了一个 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();

结果是:

Exception:1789ms 的时间成本

无异常的时间成本:0ms

这里的JObject取自Newtownsoft.Json,与Dictionary相反,没有找到key时不会抛出异常.

所以我的问题是:

  1. 异常抛出真的会减慢程序的速度吗?
  2. 可能出现多个异常时如何保证性能?
  3. 如果我真的想在这种情况下使用 Dictionary,是否可以解决?(关闭 KeyNotFoundException?)

谢谢!

【问题讨论】:

  • 异常抛出不会减慢你的程序,但捕捉会做
  • 解决方法 - 使用字典的 TryGetValue 方法,当找不到键时不会抛出异常 - 它只会返回 false。如果 key 存在,那么它将返回 true 并设置您传递的 out 参数的值
  • 如果您要测量性能,请不要在调试器下运行代码。

标签: c# performance dictionary exception


【解决方案1】:

使用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

【讨论】:

  • 谢谢,你是对的。但我想你不需要将 sum12 除以 100.0 来获得毫秒输出。
  • 如果没有异常,“ForTry”和“TryFor”给我同样的表现。这是否意味着成本是由于 throw-catch 而 try-catch 设置没有效果(编译器以某种方式优化)?dotnetfiddle.net/tTaxzG
  • @joe 如果我想获得每次通话的平均时间,我必须将 100 次通话的全部时间除以 100 才能获得一次
  • 嗯...我明白了,我在我的代码中完成了总时间。
猜你喜欢
  • 2010-11-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多