Загрузите список более эффективно

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

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

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

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

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

PS Я работаю и под другими углами, в частности, пытаюсь снизить "стоимость" GetRelativeCost, но мне нужно получить каждый цикл, который я могу использовать, чтобы сделать его приемлемым для пользователя.

2 ответа

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

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

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

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

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

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

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

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

Другие вопросы по тегам