4 вида оптимизации
Преждевременная оптимизация может быть корнем всех зол, но несвоевременная оптимизация – корень всех разочарований.
Человеческий оптимизм заставляет нас верить, что мы можем легко узнать, где программа проводит большую часть своего времени.
Человеческий оптимизм заставляет нас верить, что мы легко узнаем, как заставить медленные части программы работать быстрее.
Кроме этого, по мере того как аппаратное и программное обеспечение становятся все более сложными, все труднее становится понять, как они влияют на производительность приложения.
Мы склонны переоценивать, как много мы знаем о программном обеспечении, даже о том, над которым сейчас работаем.
Прежде чем предлагать любые оптимизации, профилируйте программу. Делайте это не один раз, а несколько, с разным набором данных и под разными условиями.
При проведении оптимизация понимание системы вширь важнее чем понимание вглубь.
Ниже приведены четыре основных вида оптимизации.
Более оптимальный алгоритм
Для большинства задач можно найти более оптимальный вариант.
Делать это нужно не в вакууме, полагаясь на теоретические знания и книги по computer science, а в контексте системы, над которой работаете.
Например, взаимосвязь между входными данными и производительностью выбранного алгоритма может быть очень тонкой. И в теории быстрый алгоритм на практики в данном конкретном проекте будет медленным. А как он будет работать в условиях многопоточности и конкурентного доступа?
Использование "лучшего алгоритма" требует понимания более широкого контекста системы и природы алгоритма, который планируете использовать.
Выбирая на чем делать акцент – худший vs лучший случай, всегда выбирайте первый.
Выбрать и, при необходимости, реализовать правильный алгоритм для решения поставленной задачи – действительно сложный навык!
Более подходящая структура данных
Как и в случае с "использованием лучшего алгоритма", "использование лучшей структуры данных" требует тщательного обдумывания и профилирования программы.
Довольно часто выходом является использования HashMap. Так, например, большое количество алгоритмических задач на LeetCode можно решить через хэш-таблицу.
Еще одна тактика, которую можно применять – писать небольшие структуры и классы. Это влияет на аллокацию памяти и нередко на общую производительность.
Если размер структуры/класса и частоту аллокаций измерить легко, то косвенное влияние таких вещей, как локальность памяти, измерить сложно.
Низкоуровневые оптимизации
Иногда переписывание на более низкоуровневый язык программирования или применение практик работы с unsafe-кодом в managed-языках действительно является правильным решением. Но сделать это редко бывает быстрой работой и неизбежно влечет за собой период нестабильности когда приходится править баги уже в новом коде.
Менее точное решение
Существует два варианта неточных решений:
возможно неоптимальные
возможно некорректное
Если не уверены, что не можете принебречь корректностью программы и/или данных, лучше явно договориться внутри команды что НЕ МОЖЕТЕ.
В случае же, когда результат работы приложения выдает не 100% оптимальное решение, это может сильно помочь в сложных оптимизациях.
Пример: точный поиск vs bloom фильтры.
Последнее обновление