Не реальный вопрос, потому что я уже нашел ответ, но все же интересная вещь.
Я всегда думал, что хеш-таблица - это самый быстрый ассоциативный контейнер, если вы правильно хешируете.
Однако следующий код ужасно медленный.Он выполняет только около 1 миллиона итераций и занимает более 2 минут времени на процессоре Core 2.
Код выполняет следующее: он поддерживает коллекцию todo
элементов, которые необходимо обработать.На каждой итерации он берет элемент из этой коллекции (не имеет значения, какой элемент), удаляет его, обрабатывает его, если он не был обработан (возможно, добавляет дополнительные элементы для обработки), и повторяет это, пока нет элементов для обработки.
Похоже, виновником является операция Dictionary.Keys.First ().
Вопрос в том, почему он медленный?
Stopwatch watch = new Stopwatch();
watch.Start();
HashSet<int> processed = new HashSet<int>();
Dictionary<int, int> todo = new Dictionary<int, int>();
todo.Add(1, 1);
int iterations = 0;
int limit = 500000;
while (todo.Count > 0)
{
iterations++;
var key = todo.Keys.First();
var value = todo[key];
todo.Remove(key);
if (!processed.Contains(key))
{
processed.Add(key);
// process item here
if (key < limit) { todo[key + 13] = value + 1; todo[key + 7] = value + 1; }
// doesn't matter much how
}
}
Console.WriteLine("Iterations: {0}; Time: {1}.", iterations, watch.Elapsed);
В результате:
Iterations: 923007; Time: 00:02:09.8414388.
Простое изменение словаря на SortedDictionary приводит к:
Iterations: 499976; Time: 00:00:00.4451514.
в 300 раз быстрее, при этом итераций всего в 2 раза меньше.
То же самое происходит в Java.Используется HashMap
вместо Dictionary
и keySet().iterator().next()
вместо Keys.First()
.