Хотите выжать из вашего кода на .NET максимум производительности? Эта книга развеивает мифы о CLR, рассказывает, как писать код, который будет просто летать. Воспользуйтесь ценнейшим опытом специалиста, участвовавшего в разработке одной из крупнейших .NET-систем в мире.
В этом издании перечислены все достижения и улучшения, внесенные в .NET за последние несколько лет, в нем также значительно расширен охват инструментов, содержатся дополнительные темы и руководства.
Author(s): Бен Уотсон ; [перевел с английского Н. Вильчинский]
Series: Серия "Для профессионалов"
Edition: 2-е изд.
Publisher: Питер
Year: 2019
Language: Russian
Pages: 415 с.
City: Санкт-Петербург
Предисловие
Об авторе
Благодарности
От издательства
Введение во второе издание
Введение
Цель этой книги
В чем смысл выбора управляемого кода?
Работает ли управляемый код медленнее нативного?
Стоит ли овчинка выделки?
Я что, теряю контроль?
Работа с CLR, а не против нее
Уровни оптимизации
Коварная соблазнительность простоты
Хронология совершенствования производительности среды .NET
.NET Core
Учебный исходный код
Глава 1. Измерение производительности и инструменты
Выбор предмета измерения
Преждевременная оптимизация
Сравнение усредненных и процентных показателей
Эталонное тестирование
Полезные инструменты
Visual Studio
Профилирование центрального процессора
Профилирование с помощью командной строки
Счетчики производительности
ETW-события
PerfView
Интерфейс и представления данных в PerfView
Профилировщик CLR Profiler
Анализатор производительности Windows Performance Analyzer
WinDbg
CLR MD
Анализаторы IL
MeasureIt
BenchmarkDotNet
Оснащение кода инструментами
Утилиты SysInternals
База данных
Другие инструменты
Издержки измерений
Резюме
Глава 2. Управление
памятью
Выделение памяти
Операция сборки мусора
Параметры конфигурации
Сравнение сборки мусора в режиме рабочей станции и в режиме сервера
Сборка мусора в фоновом режиме
Режимы задержки
Большие объекты
Дополнительные параметры
Советы по повышению производительности
Сокращайте размеры выделяемой памяти
Самое важное правило
Сокращайте время существования объекта
Сбалансируйте выделение
Сократите количество ссылок между объектами
Избегайте закреплений
Избегайте финализаторов
Избегайте выделения больших объектов
Избегайте копирования буферов
Объединяйте долгоживущие и большие объекты в пулы
Сокращайте степень фрагментации кучи больших объектов
При определенных обстоятельствах выполняйте принудительную полную сборку мусора
Уплотняйте кучу больших объектов по требованию
Получайте уведомление о намечающейся сборке мусора
Применяйте для кэширования слабые ссылки
Динамически выделяйте память в стеке
Исследование памяти и сборки мусора
Счетчики производительности
События ETW
Как выглядит куча памяти моего приложения?
Сколько времени занимает сборка мусора?
Где именно происходит выделение памяти
Что за объекты находятся в куче?
Где именно допущена утечка памяти?
Каков размер моих объектов?
Каким объектам выделена память в LOH?
Какие объекты были закреплены?
Где происходит фрагментация?
Фрагментация виртуальной памяти
В каком поколении находится объект?
Какие объекты выжили в поколении gen 0?
Откуда был сделан явный вызов метода GC.Collect?
Какие слабые ссылки имеются в моем процессе?
Какие финализируемые объекты имеются в куче?
Резюме
Глава 3. JIT-компиляция
Преимущества JIT-компиляции
JIT в действии
JIT-оптимизации
Сокращение времени JIT-компиляции и запуска
Оптимизация JIT-компиляции с помощью профилирования (Multicore JIT)
Когда следует применять NGEN
.NET Native
Настраиваемая предварительная подготовка
Когда JIT-компиляция не может составить конкуренцию
Исследование поведения JIT-компилятора
Счетчики производительности
ETW-события
Какой код подвергся JIT-компиляции?
На какие методы и модули затрачивается больше всего времени при JIT-компиляции?
Исследование кода, полученного после JIT-компиляции
Резюме
Глава 4. Асинхронное программирование
Пул потоков
Библиотека распараллеливания задач
Отмена задачи
Обработка исключений
Дочерние задачи
Среда TPL Dataflow
Параллельно выполняемые циклы
Советы по повышению производительности
Избегайте использования блокировок
Избегайте конвоев при блокировке и диспетчеризации
Использование объектов Tasks для неблокирующего ввода-вывода
async и await
О структуре программы
Правильно используйте таймеры
Подберите подходящий размер пула потоков
Не прерывайте потоки
Не меняйте приоритет потоков
Синхронизация потоков и блокировки
Нужно ли вообще заботиться о производительности?
А нужна ли вообще блокировка?
Порядок предпочтения синхронизации
Модели памяти
Использование volatile при необходимости
Использование Monitor (lock)
Использование методов Interlocked
Асинхронные блокировки
Другие механизмы блокировки
Конкурентность и коллекции
Копирование ресурса для каждого потока
Исследование потоков и конфликтов
Счетчики производительности
ETW-события
Получение информации о потоках
Визуализация задач и потоков с помощью Visual Studio
Использование PerfView для обнаружения конфликта блокировок
Где потоки блокируются на ввода-выводе?
Резюме
Глава 5. Общие подходы к написанию кода и классов
Классы и структуры
Исключение из правил: изменяемая структура для хранения иерархии полей
Виртуальные методы и запечатанные классы
Свойства
Переопределение Equals и GetHashCode для структур
Потоковая безопасность
Кортежи
Диспетчеризация интерфейсов
Избегайте упаковки
Возвращения по ссылке (ref) и локальные значения
for или foreach
Приведение типов
P/Invoke
Делегаты
Исключения
dynamic
Отражение
Генерация кода
Создание шаблонов
Создание делегата
Аргументы метода
Оптимизация
Подведение итогов
Предварительная обработка
Исследование проблем производительности
Счетчики производительности
ETW-события
Поиск инструкций упаковки
Обнаружение исключений первого шанса
Резюме
Глава 6. Использование среды .NET Framework
Разберитесь с каждым вызываемым API
Множество API для решения одних и тех же задач
Коллекции
Какие коллекции лучше не использовать
Массивы
Сравнение ступенчатых и многомерных массивов
Обобщенные коллекции
Коллекции для многопоточной среды
Коллекции для работы с битами
Исходный объем
Сравнение ключей
Сортировка
Создание собственных типов коллекций
Строки
Сравнение строк
ToUpper и ToLower
Объединение
Форматирование
ToString
Избегайте разбора строк
Подстроки
Избегайте использования API, выдающих исключения при обычных обстоятельствах
Избегайте использования API, выделяющих память из кучи больших объектов
Использование ленивой инициализации
Удивительно высокие издержки от использования перечислений
Учет времени
Регулярные выражения
LINQ
Чтение и запись файлов
Оптимизация настроек HTTP и сетевых соединений
SIMD
Исследование причин возникновения проблем с производительностью
Резюме
Глава 7. Счетчики производительности
Использование существующих счетчиков
Создание пользовательского счетчика
Счетчики усредненных показателей
Счетчики мгновенных показателей
Счетчики показателей разницы
Счетчики процентных показателей
Резюме
Глава 8. ETW-события
Определение событий
Использование пользовательских событий в PerfView
Создание пользовательского отслеживателя ETW-событий
Получение подробных данных EventSource
Использование событий CLR и системы
Пользовательские аналитические расширения PerfView
Резюме
Глава 9. Безопасность
и анализ кода
Представление об операционной системе, API и оборудовании
Ограничение использования API в определенных областях кода
Пользовательские правила FxCop
Анализаторы кода компилятора .NET
Выполняйте централизацию и абстрагирование сложного и важного для повышения производительности кода
Изолируйте неуправляемый и небезопасный код
Отдавайте приоритет ясности кода над получением высокой производительности, пока нет веских причин для обратного
Резюме
Глава 10. Формирование команды, нацеленной на достижение высокой производительности
Выявление областей, определяющих уровень производительности
Эффективное тестирование
Инфраструктура и автоматизация для оценки производительности
Доверяйте только конкретным числовым показателям
Эффективная система критической оценки кода
Обучение
Резюме
Приложение А. Начало работы над повышением производительности приложения
Определение показателей
Анализ использования центрального процессора
Анализ использования памяти
Анализ JIT-компиляции
Анализ производительности в асинхронном режиме
Приложение Б. Увеличение производительности на более высоком уровне
ASP.NET
ADO.NET
WPF
Приложение В. Обозначение «O» большого
«O» большое
Самые распространенные алгоритмы и их сложность
Сортировка
Графы
Поиск
Особый случай
Приложение Г. Библиография
Ценные источники информации
Люди и блоги