Скорость алгоритмов: O-нотацияСкорость работы алгоритмов принято оценивать в О-нотации: у медленного она «о», у более быстрого «ооо», у самого быстрого «ооооо ваще огонь».
Вру, конечно.
На самом деле, скорость оценивают в
количестве действий, которое выполняет алгоритм. Например, если у вас дома 10 котов, и нужно определить самого увесистого, то придется взвесить каждого кота, то есть выполнить 10 операций.
Алгоритм, понятное дело, должен работать одинаковым образом что для 10 котиков, что для 100, что для 10000. Оценка же скорости нужна одна. Поэтому оценивают не конкретное количество операций, а
количество операций относительно количества
входных данных (котов в нашем случае).
Если у вас
n
котов, то чтобы определить самого жирненького, придется выполнить
n
взвешиваний. В таком случае говорят, что скорость работы алгоритма —
O(n)
.
В реальности действий всегда будет не
n
, а несколько больше. Например, сначала нужно откалибровать весы, а в конце убрать их обратно в шкаф. Получается уже
n+2
действия. Но поскольку дополнительных действий константное количество, их в оценке не учитывают:
O(n+2)
=
O(n)
А что делать, если котики отказываются взвешиваться без рыбов? Тогда на каждого кота приходится 2 действия: выдать рыбку и взвесить, поэтому общее количество действий
2n
. Но фактор 2× тоже константный, поэтому и его в оценке не учитывают:
O(2n)
=
O(n)
Ровно так это работает и в коде:
var fattest Cat
for _, cat := range cats {
if cat.weight > fattest.weight {
fattest = cat
}
}
Здесь на каждого кота выполняется до трех действий:
1. Выбрать очередного кота из среза
2. Сравнить вес кота с весом жирнейшего
3. (возможно) Обновить жирнейшего
То есть действий может быть до
3n+1
(+1 — инициализация переменной
fattest
). Но скорость работы алгоритма —
O(n)
Таким образом, в O-нотации любые константные факторы игнорируются. Есть и другие нюансы, но с ними разберемся дальше по ходу дела.
P.S. Я пока не уверен, что реально нужна серия про скорость алгоритмов — может, для всех это совсем очевидная тема. Посмотрим, как пойдет.
🐈