Я ценю, что на этот вопрос уже было много ответов, но я хотел добавить небольшое исследование.
Итерация по словарю может быть довольно медленной по сравнению с итерацией по чему-то вроде массива. В моих тестах итерация по массиву занимала 0,015003 секунды, тогда как итерация по словарю (с тем же количеством элементов) занимала 0,0365073 секунды, что в 2,4 раза больше! Хотя я видел гораздо большие различия. Для сравнения, список был где-то посередине в 0,00215043 секундах.
Однако это все равно, что сравнивать яблоки и апельсины. Я хочу сказать, что итерация по словарям идет медленно.
Словари оптимизированы для поиска, поэтому с учетом этого я создал два метода. Один просто делает foreach, другой перебирает ключи, затем ищет.
public static string Normal(Dictionary<string, string> dictionary)
{
string value;
int count = 0;
foreach (var kvp in dictionary)
{
value = kvp.Value;
count++;
}
return "Normal";
}
Этот загружает ключи и перебирает их вместо этого (я также пытался вставить ключи в строку [], но разница была незначительной.
public static string Keys(Dictionary<string, string> dictionary)
{
string value;
int count = 0;
foreach (var key in dictionary.Keys)
{
value = dictionary[key];
count++;
}
return "Keys";
}
В этом примере обычный тест foreach занял 0.0310062, а версия ключей - 0.2205441. Загрузка всех ключей и итерация по всем поискам явно намного медленнее!
Для окончательного теста я выполнил свою итерацию десять раз, чтобы увидеть, есть ли какие-либо преимущества в использовании ключей здесь (к этому моменту мне было просто любопытно):
Вот метод RunTest, если он помогает вам визуализировать происходящее.
private static string RunTest<T>(T dictionary, Func<T, string> function)
{
DateTime start = DateTime.Now;
string name = null;
for (int i = 0; i < 10; i++)
{
name = function(dictionary);
}
DateTime end = DateTime.Now;
var duration = end.Subtract(start);
return string.Format("{0} took {1} seconds", name, duration.TotalSeconds);
}
Здесь обычный цикл foreach занимал 0,2820564 секунды (примерно в десять раз дольше, чем одна итерация - как и следовало ожидать). Итерация по клавишам заняла 2,2249449 секунд.
Отредактировано для добавления:
Чтение некоторых других ответов заставило меня задуматься, что произойдет, если я воспользуюсь словарем вместо словаря. В этом примере массив занял 0,0120024 секунды, список 0,0185037 секунд и словарь 0,0465093 секунд. Разумно ожидать, что тип данных влияет на то, насколько медленнее словарь.
Какие у меня выводы ?
- Избегайте итерации по словарю, если можете, они существенно медленнее, чем итерации по массиву с теми же данными в нем.
- Если вы выбираете итерацию по словарю, не пытайтесь быть слишком умным, хотя медленнее вы могли бы сделать намного хуже, чем при использовании стандартного метода foreach.