Как разделить запрос LINQ to Objects?

Это проблема распределения ресурсов. Моя цель - запустить запрос, чтобы получить сдвиг наивысшего приоритета для любого временного интервала.

Набор данных очень большой. В этом примере предположим, что на 1000 компаний приходится 100 смен в каждой (хотя реальный набор данных еще больше). Все они загружены в память, и мне нужно выполнить для них один запрос LINQ to Objects:

    var topShifts =
            (from s in shifts
            where (from s2 in shifts
                   where s2.CompanyId == s.CompanyId && s.TimeSlot == s2.TimeSlot
                   orderby s2.Priority
                   select s2).First().Equals(s)
            select s).ToList();

Проблема в том, что без оптимизации LINQ to Objects будет сравнивать каждый объект в обоих наборах, выполняя перекрестное соединение все 1, 000 x 100 против 1000 x 100, что составляет 10 миллиардов (10 000 000 000) сравнений. Я хочу сравнивать только объекты внутри каждой компании (как если бы компания была проиндексирована в таблице SQL). Это должно привести к созданию 1000 наборов объектов 100 x 100, что в сумме даст 10 миллионов (10 000 000) сравнений. Последний будет масштабироваться линейно, а не экспоненциально по мере роста числа компаний.

Такие технологии, как I4o , позволили бы мне сделать что-то подобное, но, к сожалению, я не могу позволить себе роскошь использовать пользовательский коллекция в среде, в которой я выполняю этот запрос. Кроме того, я ожидаю выполнить этот запрос только один раз для любого данного набора данных, поэтому значение постоянного индекса ограничено. Я ожидаю использовать метод расширения, который сгруппирует данные по компаниям, а затем выполнит выражение для каждой группы.

Полный пример кода:

1000 компаний x 100 смен
Заполнение данных
Завершено за 10,00 мс
Расчет высших смен
Завершено за 520 721,00 мс

смен:
C 0 Id 0 T 0 P0
C 0 Id 1 T 0 P1
C 0 Id 2 T 0 P2
C 0 Id 3 T 1 P3
C 0 Id 4 T 1 P4
C 0 Id 5 T 1 P0
C 0 Id 6 T 2 P1
C 0 Id 7 T 2 P2
C 0 Id 8 T 2 P3
C 0 Id 9 T 3 P4
C 0 Id 10 T 3 P0
C 0 Id 11 T 3 P1
C 0 Id 12 T 4 P2
C 0 Id 13 T 4 P3
C 0 Id 14 T 4 P4
C 0 Id 15 T 5 P0
C 0 Id 16 T 5 P1
C 0 Id 17 T 5 P2
C 0 Id 18 T 6 P3
C 0 Id 19 T 6 P4

Высшие смены:
C 0 Id 0 T 0 P0
C 0 Id 5 T 1 P0
C 0 Id 6 T 2 P1
C 0 Id 10 T 3 P0
C 0 Id 12 T 4 P2
C 0 Id 15 T 5 P0
C 0 Id 20 T 6 P0
C 0 Id 21 T 7 P1
C 0 Id 25 T 8 P0
C 0 Id 27 T 9 P2

Всего сравнений: 10 000 000 015,00
Любой ключ для продолжения

Вопросы:

  1. Как я могу разделить запрос (при этом выполняясь как один запрос LinQ), чтобы уменьшить количество сравнений с 10 до 10 миллионов?
  2. Есть ли более эффективный способ решения проблемы вместо подзапроса?

7
задан timherby 16 March 2011 в 19:18
поделиться