Производительность сравнения DateTime в LINQ - PullRequest
4 голосов
/ 01 августа 2011

Например, у меня есть какой-то источник данных (возможно, база данных), из которого мне нужно извлечь все записи за последний месяц. Я использую LINQ. Есть два возможных способа добиться этого:

Во-первых:

var res = from rec in _records
          where rec.RequestDateTime.Date.Year == date.Year &&
                rec.RequestDateTime.Date.Month == date.Month
          select rec;

Секунда (с использованием прямого сравнения дат):

var year = date.Year;
var month = date.Month;

var monthStart = new DateTime(year, month, 1);
var monthEnd = new DateTime(year, month, DateTime.DaysInMonth(year, month));

var res = from rec in _records
          where rec.RequestDateTime.Date >= monthStart &&
                rec.RequestDateTime.Date <= monthEnd
          select rec;

Я слышал, что второй код работает быстрее для большинства поставщиков LINQ, но не может найти никаких доказательств или объяснений (или опровержений). Итак, какой способ лучше использовать для повышения производительности и почему?

1 Ответ

11 голосов
/ 01 августа 2011

Я бы пошел дальше - IMO будет работать быстрее для почти всех провайдеров (не в последнюю очередь, LINQ-to-Objects).Когда речь идет о индексированных данных - индексы базы данных обычно сортируются, поэтому выбор, основанный на диапазоне, действительно очень быстр и прост.Для >= и <= интерпретация не требуется, и он может быстро перейти непосредственно к требуемому диапазону очень .Однако, если вы сравниваете год и месяц, у него есть два варианта:

  • вычислить год / месяц (на основе числового значения, лежащего в основе даты) и сравнить на равенство- и обратите внимание, что он может или не может использовать индекс, вместо этого ему необходимо полное сканирование
  • сделать очень умное мышление, чтобы определить, что он это диапазон (что делает анализ запроса более сложным)

Для простейшего случая (LINQ-to-Objects) то же самое верно;>= и т. Д. Тривиально - это числовое сравнение.Для тестирования месяц / год требуется , вычисление месяц / год.Эти данные не хранятся явно как целые числа и не находятся под рукой.Да, это не чрезмерно дорогих для вычисления, но при рассмотрении массовой даты, это также не бесплатно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...