Я пишу 7-карточный покерный оценщик как один из моих любимых проектов. Пытаясь оптимизировать его скорость (мне нравится задача), я был шокирован, обнаружив, что производительность поиска по словарю была довольно медленной по сравнению с поиском по индексу массива.
Например, я запустил этот пример кода, который перечисляет все 52, выберите 7 = 133 784 560 возможных 7 раздач карт:
var intDict = new Dictionary<int, int>();
var intList = new List<int>();
for (int i = 0; i < 100000; i ++)
{
intDict.Add(i, i);
intList.Add(i);
}
int result;
var sw = new Stopwatch();
sw.Start();
for (int card1 = 0; card1 < 46; card1++)
for (int card2 = card1 + 1; card2 < 47; card2++)
for (int card3 = card2 + 1; card3 < 48; card3++)
for (int card4 = card3 + 1; card4 < 49; card4++)
for (int card5 = card4 + 1; card5 < 50; card5++)
for (int card6 = card5 + 1; card6 < 51; card6++)
for (int card7 = card6 + 1; card7 < 52; card7++)
result = intDict[32131]; // perform C(52,7) dictionary key lookups
sw.Stop();
Console.WriteLine("time for dictionary lookups: {0} ms", sw.ElapsedMilliseconds);
sw.Reset();
sw.Start();
for (int card1 = 0; card1 < 46; card1++)
for (int card2 = card1 + 1; card2 < 47; card2++)
for (int card3 = card2 + 1; card3 < 48; card3++)
for (int card4 = card3 + 1; card4 < 49; card4++)
for (int card5 = card4 + 1; card5 < 50; card5++)
for (int card6 = card5 + 1; card6 < 51; card6++)
for (int card7 = card6 + 1; card7 < 52; card7++)
result = intList[32131]; // perform C(52,7) array index lookups
sw.Stop();
Console.WriteLine("time for array index lookups: {0} ms", sw.ElapsedMilliseconds);
который выводит:
time for dictionary lookups: 2532 ms
time for array index lookups: 313 ms
Ожидается ли этот тип поведения (снижение производительности в 8 раз)? IIRC, Словарь имеет в среднем O (1) поисков, в то время как массив имеет O (1) поисков в худшем случае, поэтому я ожидаю, что поиск в массиве будет быстрее, но не настолько сильно!
В настоящее время я храню рейтинг покерных рук в Словаре. Я полагаю, если это так быстро, как это возможно при поиске в словаре, мне придется переосмыслить свой подход и вместо этого использовать массивы, хотя индексация рейтинга будет немного сложнее, и мне, вероятно, придется задать еще один вопрос по этому поводу.