C# 在字典上使用foreach循环进行迭代是否需要正常的哈希表访问?
我正在编写一个主要是性能密集型的应用程序。在今天编写了一个快速基准测试之后,我发现字典访问时间明显慢于数组访问时间(高达100倍),尽管两者都是O(1)。我试图在互联网上找到类似的结果,但没有结果。这看起来对吗?这对我来说很有意义,因为字典中涉及哈希,而数组中不涉及哈希 我现在正在权衡字典的利弊,并考虑是否应该尝试更快的实现。在我的应用程序的至少3个实例中,我使用foreach循环遍历我的所有字典(有很多字典)。那么现在来回答我的问题,foreach循环是否必须经过“缓慢”(我在这里相对地说)散列过程,或者它只是维护一个可以快速迭代的内部列表?如果是这样的话,我更愿意坚持使用字典 对于一些额外的信息,应用程序是一个简单的2D游戏,字典将存储在游戏实体中。但是确实有很多。是的,我已经有了一个可行的解决方案。这是后期优化,而不是前期优化 这是我写的基准。这可能是非常错误的,因为我不是该领域的专家:C# 在字典上使用foreach循环进行迭代是否需要正常的哈希表访问?,c#,.net,performance,dictionary,C#,.net,Performance,Dictionary,我正在编写一个主要是性能密集型的应用程序。在今天编写了一个快速基准测试之后,我发现字典访问时间明显慢于数组访问时间(高达100倍),尽管两者都是O(1)。我试图在互联网上找到类似的结果,但没有结果。这看起来对吗?这对我来说很有意义,因为字典中涉及哈希,而数组中不涉及哈希 我现在正在权衡字典的利弊,并考虑是否应该尝试更快的实现。在我的应用程序的至少3个实例中,我使用foreach循环遍历我的所有字典(有很多字典)。那么现在来回答我的问题,foreach循环是否必须经过“缓慢”(我在这里相对地说)散
public static int dict(Dictionary<key,int> dict, key k)
{
int i;
//dict.TryGetValue(k,out i);
i = dict[k]; //both these version yield the same results
return i;
}
public static int arr(int[,] arr, key k)
{
int i;
i = arr[k.x, k.y];
return i;
}
public struct key
{
public int x, y;
public key (int x, int y){
this.x = x;
this.y = y;
}
}
public static void Main()
{
int dim = 256;
Dictionary<key,int> dictVar = new Dictionary<key,int>(dim*dim*10);
int[,] arrVar = new int[dim,dim];
for (int i = 0; i < dim; ++i)
{
for (int j = 0; j < dim; ++j)
{
arrVar[i, j] = i + j * i;
dictVar.Add(new key(i, j), i + i * j);
}
}
const int iterations = 1000000;
key k = new key(200, 200);
TestTime(dict, dictVar, k, iterations);
TestTime(arr, arrVar, k, iterations);
}
public static void TestTime<T1, T2, TR>(Func<T1, T2, TR> action, T1 obj1,
T2 obj2, int iterations)
{
Stopwatch stopwatch = Stopwatch.StartNew();
for (int i = 0; i < iterations; ++i)
action(obj1, obj2);
Console.WriteLine(action.Method.Name + " took " + stopwatch.Elapsed);
}
public static int dict(字典dict,k键)
{
int i;
//dict.TryGetValue(k,out i);
i=dict[k];//这两个版本产生相同的结果
返回i;
}
公共静态int-arr(int[,]arr,键k)
{
int i;
i=arr[k.x,k.y];
返回i;
}
公共结构密钥
{
公共整数x,y;
公钥(整数x,整数y){
这个.x=x;
这个。y=y;
}
}
公共静态void Main()
{
int dim=256;
Dictionary dictVar=新字典(dim*dim*10);
int[,]arrVar=新int[dim,dim];
对于(int i=0;i
它维护一个循环的内部列表,但该列表的类型为条目[]
,因此每次都必须构造一个KeyValuePair。我想这就是造成减速的原因。你是如何反复浏览字典的foreach(dict.Keys中的var-key){var-value=dict[key];}
比foreach(dict中的var-item){var-key=item.key;var-value=item.value;}
慢得多。发布用于运行基准测试的代码。我正在做foreach(dict中的var-item)。在这种情况下,我实际上根本不需要钥匙。只有值很重要。使用它应该比使用foreach
更快。字典不是为枚举而设计的,而是为通过键访问单个项目而设计的。@TheevillPenguin:它省略了异常处理。我想这回答了我的问题,谢谢。可以在2分钟内接受:)