C#异常的性能成本

C#异常的性能成本,c#,performance,dictionary,exception,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

我正在构建一个项目,其中配置文件将作为字典加载。为了防止配置无效,我只添加了一个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();
var temp=newdictionary{[“hello”]=“world”};
var tempj=newjobject(){[“hello”]=“world”};
秒表sw=新秒表();
sw.Start();
对于(int i=0;i<100;i++)
{
尝试
{
var值=温度[“错误”];
}
抓住
{
//忽略
}
}
sw.Stop();
Console.WriteLine(“异常时的时间成本:+sw.elapsedmillyses+“ms”);
sw.Restart();
对于(int i=0;i<100;i++)
{
var value=tempj[“error”];//等效于value=null
}
Console.WriteLine(“时间成本无一例外:+sw.elapsedmillyses+“ms”);
Console.ReadLine();
结果是:

异常的时间成本:1789ms

无一例外的时间成本:0毫秒

这里的JObject取自Newtownsoft.Json,与Dictionary相反,Newtownsoft.Json在找不到键时不会引发异常

所以我的问题是:

  • 异常抛出真的会让程序慢那么多吗
  • 当可能发生多个异常时,如何保证性能
  • 无论如何,如果我真的想在这种情况下使用字典,请解决这个问题?(关闭KeyNotFoundException?)

  • 谢谢大家!

    使用
    Dictionary.TryGetValue
    避免示例代码中出现异常。最昂贵的部分是
    try。。捕捉

    如果无法避开异常,则应使用不同的模式在循环内执行操作

    而不是

    for ( i = 0; i < 100; i++ )
        try
        {
            DoSomethingThatMaybeThrowException();
        }
        catch (Exception)
        {
            // igrnore or handle
        }
    
    只会设置一个新的
    try。。抛出异常时捕获

    顺便说一句


    我无法重现您描述的代码的大幅减速

    异常抛出不会降低程序的速度,但捕获将是可行的-使用字典的
    TryGetValue
    方法,当找不到键时不会抛出异常-它只会返回
    false
    。如果键在那里,那么它将返回
    true
    并设置要传递的
    out
    参数的值如果要测量性能,不要在调试器下运行代码。谢谢,你是对的。但是我想你不需要将sum12除以100.0来获得毫秒的输出。如果没有异常,“ForTry”和“TryFor”给了我同样的性能。这是否意味着成本是由于抛出catch,而try catch设置没有效果(以某种方式由编译器优化)?@joe如果我想得到每个调用的平均时间,我必须将100个调用的整个时间除以100才能得到一个,嗯……我明白了,我在代码中计算了总时间。
    int i = 0;
    while ( i < 100 )
        try
        {
            while( i < 100 )
            {
                DoSomethingThatMaybeThrowException();
                i++;
            }
        }
        catch ( Exception )
        {
            // ignore or handle
            i++;
        }