2013-03-11 9 views
0

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

List<MyObject> _moList = new List<MyObject>(DB.GetAll(queryString, parameters, MyObject.Extract)); 
_moList.AsParallel().ForAll(s => s.RelativeCost = GetRelativeCost(s)); 

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

Некоторые элементы не в том, что MyObject имеет около сорока свойств (не уверен, что это уместно или нет), и GetRelativeCost несколько дороже, когда дело доходит до циклов времени/процессора (отсюда параллельный запуск).

Любая помощь была бы принята с благодарностью!

P.S. Я также работаю с другими углами, в частности, пытаясь уменьшить «стоимость» GetRelativeCost, но мне нужно получить каждый цикл, который я могу извлечь из этого, чтобы сделать его приемлемым для пользователя.

+1

похоже, что вы идете в базу данных ... вы профилировали запрос, чтобы узнать, можно ли его ускорить? – kzhen

+0

Вы хотите улучшить среднюю производительность (в течение срока службы приложения) или наихудший показатель производительности при каждом прогоне?Если первый, вы можете попробовать кэшировать результат каждый раз и тестировать, чтобы увидеть, были ли исходные данные изменены до перезагрузки. –

+0

Почему вы используете 'AsParallel', а не' Parallel.ForEach'? –

ответ

0

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

(new List<MyObject>(DB.GetAll(queryString, parameters, MyObject.Extract))).AsParallel().ForAll(s => s.RelativeCost = GetRelativeCost(s)); 

Но, не ожидайте, что это улучшит производительность вашего кода.

1
  1. У вас есть профайлер? Вы уверены, что оптимизируете узкое место?
  2. Почему вы пытаетесь оптимизировать обработку списка, а не GetRelativeCost?
  3. Что такое DB.GetAll? Вы уверены, что он работает оптимально?
  4. Предполагаю ли я, что правильный MyObject.Extract - это какая-то функция гидратации объекта? Вы уверены, что это оптимально?
  5. Почему GetRelativeCost Выполняется по списку loading? Не имеет смысла откладывать его исполнение?

Подробнее о последнем пункте. Если у вашего GetRelativeCost есть некоторые побочные эффекты - вы все равно должны их удалить, так как это нарушение принципа СУХОЙ. Если нет, то вы можете переписать RelativeCost для обеспечения отложенной инициализации, как

private int? _relativeCost 
public int RelativeCost { 
    get { 
     if (!_relativeCost.HasValue) 
      _relativeCost = GetRelativeCost(); 
     return _relativeCost; 
    } 
} 

Таким образом, вы задержать GetRelativeCost выполнения, пока это действительно не нужно. таким образом, вы оптимизируете, не вычисляя GetRelativeCost для объектов, которые действительно не нуждаются в RelativeCost, а также ускоряют этот конкретный кусок кода, задерживая дорогостоящие вычисления в GetRelativeCost по стоимости увеличенных вычислений позже.

Подводя итог: проложить профайлер, определить узкое место, оптимизировать узкое место. Если узкое место, похоже, находится в GetRelativeCost - попробуйте сделать его ленивым, как я описал выше.

+0

1. Да, несколько раз 2. Я также пытаюсь оптимизировать получение относительной стоимости 3. Без контроля над этим. Это DB.GetAll ссылается на стороннюю сборку, к которой у меня нет исходного кода. Для удаления всех ссылок потребуется переписать код. 4. Я открыт для предложений. Смотри ниже. –

+0

5. a - Следующая строка - _objectCache = new List (_ moList.Select (s => новый MyObjectDisplayer (s))); 'Затем мне нужно получить доступ к объекту через другой объект. Перемещение его в список загрузки сократило мое время примерно на 10%. –

+0

b - MyObject является частью более крупной конструкции. Чтобы рассчитать стоимость, он должен был бы знать эту большую конструкцию. Например, большая конструкция может иметь ширину 48 дюймов. MyObject может быть 8, 12, 24 или 48 inces. 8-дюймовый имеет более высокую стоимость, чем 48-дюймовый, потому что для этого требуется 6. Было бы лучше сделать ленивую загрузку, если MyObject узнает о ее родительском объекте, или родитель подсчитает стоимость, основанную на детях? –

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