Also, can this notion be used in a practical fashion to improve an algorithm? If so, how?
Он используется не столько для улучшения алгоритма, сколько для оценки производительности алгоритмов и выбора алгоритма, который вы решите использовать.Для любой данной проблемы вы действительно хотите избегать алгоритмов, которые имеют O (N!) Или O (N ^ x), так как они резко замедляются при увеличении размера N (вашего ввода).То, что вы хотите, это O (N) или O (log (N)) или, что еще лучше, O (1).
O (1) - это постоянное время, что означает, что для выполнения алгоритма требуется то же количество времени, что и длямиллион входов, как это делается для одного.O (N), конечно, линейный, что означает, что время, необходимое для выполнения алгоритма, увеличивается пропорционально его вводу.
Есть даже некоторые проблемы, когда любой алгоритм, разработанный для их решения, в конечном итоге становится O (N!).В принципе, быстрый алгоритм не может быть разработан для полного решения проблемы (этот класс проблем известен как NP-полный).Как только вы поймете, что имеете дело с такой проблемой, вы можете немного ослабить свои требования и решить проблему не лучшим образом, «обманывая».Эти читы не обязательно находят оптимальное решение, но вместо этого соглашаются на достаточно хорошее.Мои любимые читы - это генетические / эволюционные алгоритмы и радужные таблицы.
Еще один пример того, как понимание сложности алгоритмов меняет ваши взгляды на программирование, - это микрооптимизации.Вернее, не делать этого.Вы часто видите, как новички задают такие вопросы, как is ++x faster than x++
.Опытным программистам, в основном, все равно, и они обычно отвечают: the first rule of optimization is: don't
.
Более полезный ответ должен состоять в том, что изменение x++
на ++x
никак не повлияет на сложность вашего алгоритма.Сложность вашего алгоритма оказывает гораздо большее влияние на скорость вашего кода, чем любая форма микрооптимизации.Например, для вас гораздо более продуктивно смотреть на ваш код и сокращать количество глубоко вложенных циклов, чем беспокоиться о том, как ваш компилятор превращает ваш код в сборку.
Еще один пример - какВ программировании игр ускорение кода противоречит интуитивно понятному принципу: добавление еще большего количества кода вместо сокращения кода.Добавленный код представлен в виде фильтров (в основном, если ... другие операторы), которые решают, какой бит данных нуждается в дальнейшей обработке, а какой можно отбросить.С точки зрения микрооптимизатора, добавление кода означает больше инструкций для процессора.Но на самом деле эти фильтры уменьшают проблемное пространство, отбрасывая данные и, следовательно, работают быстрее в целом.