2013-12-17 7 views
1

У меня есть два разных списка объектов, один из которых - набор IQueryable (свернутый в массив), а другой набор List. Объекты в обоих наборах совместно используют поле с именем ID; каждый из объектов во втором наборе будет соответствовать объекту в первом наборе, но не обязательно наоборот. Мне нужно иметь возможность обрабатывать обе группы (согласованные и непревзойденные). Размер обоих коллекций в этом случае составляет от 300 до 350 объектов (для справки, XML, сгенерированный для объектов во втором наборе, обычно не больше 7k, так что подумайте, может быть, от половины до двух третей этого размера для реальной памяти используемые каждым объектом в каждом наборе).C# Соответствующие элементы в разных списках

Способ, которым он в настоящее время настроен, представляет собой цикл for, который выполняет итерацию через представление массива набора IQueryable, используя оператор LINQ для запроса набора List для соответствующей записи. Это занимает слишком много времени; Я запускаю Core i7 с 10 ГБ оперативной памяти и занимает от 10 секунд до 2,5 минут, чтобы сопоставлять и сравнивать объекты. Диспетчер задач не показывает огромного использования памяти - оттенок под 25 МБ. Ни один из моих системных потоков не облагается налогом.

Есть ли метод или алгоритм, который позволил бы мне одновременно соединять объекты в каждом наборе и, таким образом, быстрее и быстрее проходить через пары и непревзойденные объекты? Этот набор объектов лишь малая часть из 8000 + этой программы будет иметь жевать через каждый день, когда он идет жить ...

EDIT: Вот код, я на самом деле работаю ...

 for (int i = 0; i < draftRecords.Count(); i++) 
     { 
      sRecord record = (from r in sRecords where r.id == draftRecords.ToArray()[i].ID select r).FirstOrDefault(); 
      if (record != null) 
      { // Do stuff with the draftRecords element based on the rest of the content of the sRecord object 

ответ

2

Вы должны использовать метод, такой как Enumerable.Join или Enumerable.GroupJoin для соответствия элементам из двух коллекций. Это будет намного быстрее, чем выполнение вложенных циклов.

Поскольку вы хотите совместить коллекцию ключей с элементом во втором списке, который может быть или не существовать, возможно, более подходящим является GroupJoin. Это будет выглядеть примерно так:

var results = firstSet.GroupJoin(secondSet, f => f.Id, s => s.Id, (f,sset) => new {First = f, Seconds = sset}); 

foreach(var match in results) 
{ 
    Console.WriteLine("Item {0} matches:", match.First); 
    foreach(var second in item.Seconds) 
     Console.WriteLine(" {0}", second); // each second item matching, one at a time 
} 
+0

Спасибо! Я дам ему шанс и посмотрю, как это происходит. – Ant

+0

@Ant Вставьте код для демонстрации –

1

Ваш вопрос отсутствует в образце кода/информации, но я лично хотел бы использовать такие методы, как; Присоединяться, пересекать или содержать. При необходимости используйте «Выбрать», чтобы выполнить проецирование полей, которые вы хотите сопоставить, или определить пользовательский номер IEqualityComparer.

Смежные вопросы