Продолжая тему того, что оптимизации применяются, причём в разных местах и весьма часто. Причём не хардкорные, а самые что ни на есть простейшие. И не по CPU, а по памяти.
Вот тут ребята из PVS-Studio узнали, что:
- Надо использовать правильный алгоритм. Это видно на примере их внутреннего кэша, где они складировали в память всё подряд. К кэшу в памяти надо всегда подходить с умом, так как кэш может распухнуть, а его данные вообще попасть в LOH.
- Одинаковые строки надо пропускать через string.Intern - это сильно экономит память. Опять таки, делать это надо осторожно.
- ToString создаёт... строку. Причём, иногда, по сложному алгоритму. Если таких вызовов много, то строки аллоцируются, память неумолимо заканчивается, GC не успевает. Не надо так, особенно в горячих местах кода.
- Итерация по IEnumerable несколько дорогая по памяти, если расположена в горячем месте. Это актуально для IList, IReadonlyList и прочих ICollection. Просто потому, что IEnumerator, который возвращается из IEnumerable.GetEnumerator(), хоть и структура по определению, но размещается в куче по использованию (boxing). Итерируйтесь по классам коллекций, это дешевле.
- LINQ это красиво, но очень дорого по памяти в горячих местах кода. Во-первых, произойдёт boxing IEnumerator как в пункте выше. Во-вторых, сами методы тоже иногда кое-что аллоцируют. Ну и скорость работы несколько ниже простого foreach. Разверните все LINQ в foreach в горячих местах кода.
- LINQ это штука, которая может выполняться несколько раз. Она ведь с отложенным выполнением. Значит каждый раз, когда мы будем передавать её в различные методы, каждый раз будет выполняться последовательность действий в цепочке выражений. Это дорого по CPU и по памяти. Не надо так. Лучше и дешевле материализовать результат один раз, сложить его в какой-нибудь массив, взятый из ArrayPool, и потом благополучно вернуть обратно.
Короче говоря, коллеги впечатлены: на некоторых проектах скорость работы увеличилась более чем на 20%, а пиковое потребление памяти сократилось практически на 70% (цитата из статьи). Что тут сказать? Только пожелать удачи и напомнить, что для некоторых типов задач не работает знаменитое правило о том, что преждевременная оптимизация это плохо. Увы, в некоторых проектах надо сразу писать код с оглядкой на память и CPU. Это окупится трижды, не потребует затрат на исследование возникших проблем и снизит негатив от пользователей.
P.S.: Понимаю, что статья старая, но очень уж показательная. Проблем с памятью не ожидаешь от инструмента, который, вроде бы, должен работать на пользовательских машинах.
Мой канал в TG: https://t.me/csharp_gepard