Я пишу простое приложение для разбора огромного текстового файла (60 ГБ) и сохранения всех слов и времени, в течение которого оно появляется в файле.Для тестирования я сократил файл до 2 ГБ.
У меня есть слова и цифры в словаре, хотя мне трудно поверить в результаты, которые я вижу.
Итогослов в словаре: 1128495
Код, который я использую:
sw.Start();
StringBuilder sb = new StringBuilder();
sb.AppendFormat("<html><head></head><body>");
lock (Container.values)
{
int i = int.Parse(ctx.Request.QueryString["type"]);
switch (i)
{
case 1: //LinQ
var values = Container.values.OrderByDescending(a => a.Value.Count).Take(100);
foreach (var value in values)
{
sb.AppendFormat("{0} - {1}<br />", value.Key, value.Value.Count);
}
break;
case 2: //Foreach
foreach (var y in Container.values)
{
}
break;
case 3: //For
for (int x = 0; x < Container.values.Count; x++)
{
}
break;
}
}
sw.Stop();
sb.AppendFormat("<br /><br /> {0}", sw.ElapsedMilliseconds);
sb.AppendFormat("</body>");
Запустил его дважды, скорости ниже в миллисекундах:
LinQ: # 1: 598,# 2 609
Foreach: # 1 1000, # 1020
Почему LinQ быстрее, чем foreach?Я предполагаю, что LinQ должен циклически проходить по самому Словарю, так как это происходит + сортировка всего этого своевременно?
Редактировать: После компиляции в режиме Release результаты выглядят следующим образом: LinQ: 796 (медленнее?) foreach: 945
Приложение представляет собой простое консольное приложение, код выполняется в HttpListener
Редактировать 2: Мне удалось выяснить, в чем проблема.Когда я инициализировал словарь, я установил его емкость равной 89000000 (в противном случае при обработке файла объемом 60 Гб будет выдано исключение OutOfMemory).По какой-то причине это резко замедляет работу цикла foreach.Если я установлю емкость на 1128495, цикл foreach выполняется за 56 миллисекунд.
Почему это происходит?Если я добавлю счетчик в цикл, он будет работать только 1128495 раз, даже с емкостью 89000000.