我有一个生成的Vector2的列表,我必须检查字典,看看它们是否存在,这个函数每个节拍都会被执行。
哪一个跑得最快/这样做更好?
public static bool exists(Vector2 Position, Dictionary<Vector2, object> ToCheck)
{
try
{
object Test = ToCheck[Position];
return (true);
}
catch
{
return (false);
}
}或者我应该坚持常态?
public static bool exists(Vector2 Position, Dictionary<Vector2, object> ToCheck)
{
if (ToCheck.ContainsKey(Position))
{
return (true);
}
return (false);
}感谢您的投入:)
附注:(键的值在这一点上无关紧要,否则我将使用TryGetValue而不是ContainsKey)
发布于 2012-09-14 08:45:58
一定要使用ContainsKey检查;异常处理可以add a large overhead。
抛出异常可能会对性能产生负面影响。对于经常失败的代码,可以使用设计模式将性能问题降到最低。
异常不适用于您可以检查的条件。
我推荐阅读关于exceptions generally的MSDN文档,特别是关于exception handling的文档。
发布于 2012-11-02 20:05:47
我知道这是个老生常谈的问题,但我想补充一点经验数据...
在包含10,000个条目的字典上运行50,000,000次查找,并比较完成所需的相对时间:
..if每次查找都是成功的:
每10,000次查找中有1次..if失败:
2
每10,000次查找中有16次..if失败:
2
每10,000次查找中有250次..if失败:
2
..so一个有保护的测试将增加一个恒定的开销,没有更多的东西,并且try-catch测试将几乎和没有测试一样快,如果它永远不会失败,但会与失败的数量成比例地杀死性能。
我用来运行测试的代码:
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);
}
}
}发布于 2012-09-14 08:48:25
切勿将try/catch用作常规程序路径的一部分。它的开销非常大,而且应该只捕获您无法防止的错误。ContainsKey就是这方面的发展方向。
附注:不是。你不会的。如果该值很重要,您可以使用ContainsKey检查它是否存在,如果存在,则检索它。不是try/catch。
https://stackoverflow.com/questions/12416735
复制相似问题