我正在编写一个主要是性能密集型的应用程序。在今天编写快速基准之后,我发现字典访问时间明显慢于数组访问时间(最多100次),尽管两者都是O(1)。我尝试在互联网上找到类似的结果,但无济于事。这看起来是对的吗?这对我来说很有意义,因为字典中有哈希,而不是数组。
我现在正在权衡字典的优缺点,并考虑是否应该尝试更快的实现。在我的应用程序的至少3个实例中,我使用foreach循环遍历我的所有词典(有很多)。所以现在要回答我的问题,foreach循环是否必须经历“慢”(我在这里相对而言)散列过程,或者它是否只是维护一个可以快速迭代的内部列表?如果是这种情况,我更有可能坚持使用字典。
对于一些额外信息,应用程序是一个简单的2D游戏,字典将存储在游戏实体中。虽然确实有很多。是的,我已经有了一个有效的解决方案。这是后优化,而不是预先。
这是我写的基准。这可能是非常错误的,因为我不是该领域的专家:
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);
}
答案 0 :(得分:1)
它维护一个循环的内部列表,但列表的类型为Entry<TKey, TValue>[]
,因此每次都必须构造一个KeyValuePair。我猜这是造成经济放缓的原因。