首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Containskey VS Try Catch

Containskey VS Try Catch
EN

Stack Overflow用户
提问于 2012-09-14 08:43:52
回答 4查看 4.4K关注 0票数 11

我有一个生成的Vector2的列表,我必须检查字典,看看它们是否存在,这个函数每个节拍都会被执行。

哪一个跑得最快/这样做更好?

代码语言:javascript
复制
    public static bool exists(Vector2 Position, Dictionary<Vector2, object> ToCheck)
    {
        try
        {
            object Test = ToCheck[Position];
            return (true);
        }
        catch 
        {
            return (false);
        }           
    }

或者我应该坚持常态?

代码语言:javascript
复制
    public static bool exists(Vector2 Position, Dictionary<Vector2, object> ToCheck)
    {
        if (ToCheck.ContainsKey(Position))
        {
            return (true);
        }
        return (false);
    }

感谢您的投入:)

附注:(键的值在这一点上无关紧要,否则我将使用TryGetValue而不是ContainsKey)

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-09-14 08:45:58

一定要使用ContainsKey检查;异常处理可以add a large overhead

抛出异常可能会对性能产生负面影响。对于经常失败的代码,可以使用设计模式将性能问题降到最低。

异常不适用于您可以检查的条件。

我推荐阅读关于exceptions generally的MSDN文档,特别是关于exception handling的文档。

票数 18
EN

Stack Overflow用户

发布于 2012-11-02 20:05:47

我知道这是个老生常谈的问题,但我想补充一点经验数据...

在包含10,000个条目的字典上运行50,000,000次查找,并比较完成所需的相对时间:

..if每次查找都是成功的:

  • 直接(未选中)运行需要1.2秒
  • 保护(ContainsKey)运行需要2秒
  • 已处理(尝试-捕获)运行需要1.21秒

每10,000次查找中有1次..if失败:

  • a guarded (ContainsKey) run

2

  • a handled (try-
  • ) run takes 1.37秒

每10,000次查找中有16次..if失败:

  • a
    • a guarded (ContainsKey) run

    2

    • a handled (try-catch) run takes 3.27秒

每10,000次查找中有250次..if失败:

  • a guarded (ContainsKey) run

2

  • a handled (try-
  • ) run takes 32秒

..so一个有保护的测试将增加一个恒定的开销,没有更多的东西,并且try-catch测试将几乎和没有测试一样快,如果它永远不会失败,但会与失败的数量成比例地杀死性能。

我用来运行测试的代码:

代码语言:javascript
复制
using System;
using System.Collections.Generic;

namespace ConsoleApplication1
{
   class Program
   {
      static void Main(string[] args)
      {  Test(0);
         Test(1);
         Test(16);
         Test(250);
      }

      private static void Test(int failsPerSet)
      {  Dictionary<int, bool> items = new Dictionary<int,bool>();

         for(int i =  0; i < 10000; i++)
            if(i >= failsPerSet)
               items[i] = true;

         if(failsPerSet == 0)
            RawLookup(items, failsPerSet);

         GuardedLookup(items, failsPerSet);

         CaughtLookup(items, failsPerSet);

      }

      private static void RawLookup
      (  Dictionary<int, bool> items
      ,  int             failsPerSet
      ){ int                   found = 0;
         DateTime              start ;

         Console.Write("Raw     (");
         Console.Write(failsPerSet);
         Console.Write("): ");

         start = DateTime.Now;
         for(int i = 0; i < 50000000; i++)
         {  int pick = i % 10000;
            if(items[pick])
               found++;
         }

         Console.WriteLine(DateTime.Now - start);
      }

      private static void GuardedLookup
      (  Dictionary<int, bool> items
      ,  int             failsPerSet
      ){ int                   found = 0;
         DateTime              start ;

         Console.Write("Guarded (");
         Console.Write(failsPerSet);
         Console.Write("): ");

         start = DateTime.Now;
         for(int i = 0; i < 50000000; i++)
         {  int pick = i % 10000;
            if(items.ContainsKey(pick))
               if(items[pick])
                  found++;
         }

         Console.WriteLine(DateTime.Now - start);
      }

      private static void CaughtLookup
      (  Dictionary<int, bool> items
      ,  int             failsPerSet
      ){ int                   found = 0;
         DateTime              start ;

         Console.Write("Caught  (");
         Console.Write(failsPerSet);
         Console.Write("): ");

         start = DateTime.Now;
         for(int i = 0; i < 50000000; i++)
         {  int pick = i % 10000;
            try
            {  if(items[pick])
                  found++;
            }
            catch
            {  
            }
         }

         Console.WriteLine(DateTime.Now - start);
      }

   }
}
票数 27
EN

Stack Overflow用户

发布于 2012-09-14 08:48:25

切勿将try/catch用作常规程序路径的一部分。它的开销非常大,而且应该只捕获您无法防止的错误。ContainsKey就是这方面的发展方向。

附注:不是。你不会的。如果该值很重要,您可以使用ContainsKey检查它是否存在,如果存在,则检索它。不是try/catch。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12416735

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档