Загрузите список более эффективно
Мне было поручено обновить какой-то устаревший код, и мне действительно нужно сократить время выполнения его части. Список ниже загружается довольно часто. Мне удалось сократить время примерно с минуты до пятнадцати секунд, но мне действительно нужно идти дальше. Следующие строки кода работают довольно хорошо, но я пытаюсь выжать из него все, что могу.
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 ответа
- Вы запускали профилировщик? Вы уверены, что оптимизируете узкое место?
- Почему вы пытаетесь оптимизировать обработку списка, а не
GetRelativeCost
? - Что
DB.GetAll
? Вы уверены, что он работает оптимальным образом? - Я правильно понимаю
MyObject.Extract
это какая-то функция гидратации объекта? Вы уверены, что это оптимально? - Зачем
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));
Но не ожидайте, что это улучшит производительность вашего кода.