2015-09-17 5 views
2

У меня есть инструкция foreach внутри другого заявления foreach, которое занимает очень много времени для повторения. (Там много записей). Есть ли способ упростить этот код? Возможно, с Линком? Вот мой код:Оператор Foreach занимает длинное

IList<SourceCounterPartyExposure_Limit> exposures = new List<SourceCounterPartyExposure_Limit>(); 

foreach (SourceCounterParty counterParty in limit.SourceCounterParties) 
{ 
    foreach (SourceCounterPartyExposure_Limit exposure in counterParty.LimitExposures) 
    { 
     if (!exposures.Contains(exposure)) 
     { 
      arExposures += exposure.ARExposure; 
      mtmExposures += exposure.MTMExposure; 
      volumeExposures += exposure.ConvertedVolume; 
      if (maxTenorExposures < exposure.MaxTenor) 
      {maxTenorExposures = exposure.MaxTenor; } 
      exposures.Add(exposure); 
     } // if 
    } // foreach 
}// foreach 

ответ

2

Попробуйте один цикл по:

limit.SourceCounterParties.SelectMany(x => x.LimitExposures).Distinct() 

Таким образом, вы (я) только получать различные записи обратно из базы данных и (б) позволяет Entity Framework для перевода ваш запрос в то, что выполняется в базе данных.

Вы также можете использовать Sum и Max, чтобы создать единый запрос, который будет выполняться в базе данных.

3

Можно, конечно, упростить код:

IEnumerable<Exposure> exposures = 
    limit.SourceCounterParties.SelectMany(e => e.LimitExposures).Distinct() 

коллапсирует как ваши петли и если заявление. Вы можете foreach над этим и запустить свой код:

foreach (Exposure exposure in exposures) 
{ 
    arExposures += exposure.ARExposure; 
    mtmExposures += exposure.MTMExposure; 
    volumeExposures += exposure.ConvertedVolume; 
    if (maxTenorExposures < exposure.MaxTenor) 
     {maxTenorExposures = exposure.MaxTenor; 
} 

Это, как говорится, его еще большой перечень, вы не собираетесь, чтобы получить тонну скорости здесь.

+0

Yup. Улучшения производительности будут относительно небольшими, поскольку то, что пытается сделать @EB, неявно дорого, но это хороший шаг вперед. –

0

Одна из возможных причин для замедления кода это условие:

if (!exposures.Contains(exposure)) 

Если окончательный заказ или детали не имеет значения, или вы можете сортировать их позже, я хотел бы предложить вам заменить его

var exposures = new HashSet<SourceCounterPartyExposure_Limit>(); 

Если класс SourceCounterPartyExposure_Limit имеет хорошую хэш-функцию, то поиск должен быть быстрым (близко к O (1)), и это может значительно повысить общую производительность вашего кода.

Возможно, вы можете изменить алгоритм для запуска в нескольких потоках, а затем объединить результаты. Но не уверен, что это подходит для вас.

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