Bug O нотация: отладочная сложность программных интерфейсов

0
2648
Добавить в избранное

Про Big O нотацию вы наверняка сами знаете, а мы вам расскажем про Bug O нотацию и отладочную сложность программных интерфейсов.

Bug O нотация: отладочная сложность программных интерфейсов

Хотите писать эффективный и высокопроизводительный код? Тогда вы непременно должны учитывать его алгоритмическую сложность – то, что также известно под кодовым именем Big O нотация.

Big O описывает, насколько медленнее станет выполняться ваш код, если увеличить размер входных данных. Для примера возьмем сортировку. Сложность O(n2) означает, что если входной массив увеличится в 50 раз, то время выполнения алгоритма вырастет аж в 502 = 2500 раз!

Big O нотация – это не точное число, она дает лишь общее представление о масштабируемости алгоритма, например, O(n), O(n log n), O(n2), O(n!).

Читайте также:

На этом разговор про алгоритмы и производительность мы заканчиваем. Цель статьи – обсуждение программных интерфейсов и отладки программ. Вроде бы темы не связанные друг с другом, однако вы удивитесь, как много между ними общего.

Огромная доля нашего рабочего времени уходит на поиск и исправление ошибок. И чем больше кода – тем больше времени.

Некоторые API и языковые конструкции устроены так, что делают невозможным допущение целых классов ошибок, а другие, наоборот, создают бесконечные проблемы на пустом месте. Как же понять, кто из них кто?

Мы часто спорим об изящности наших программных интерфейсов, но иногда забываем, что изящность и опыт практического использования – это разные вещи. Чтобы оценить, насколько замедляет вас ваш API по мере роста кодовой базы, введем новую нотацию: Bug O.

Отладочная сложность: 🐞(n)

Big O описывает, как замедляется алгоритм, Bug O – как замедляетесь вы.

Посмотрим на реальном примере. Есть довольно неструктурированный код, вручную обновляющий DOM с помощью императивных операций вроде node.appendChild() и node.removeChild().

Проблема не в том, что этот код уродлив. Мы не обсуждаем эстетику. Проблема в том, как вы будете искать здесь ошибку, если она возникнет.

Читайте также:

В зависимости от порядка отработки событий и обратных вызовов вы можете получить огромное количество возможных путей развития этой программы. В некоторых из них все хорошо. Но в других – несколько спиннеров, сообщения об ошибках и, возможно, сбои.

Здесь четыре секции кода и никакой гарантии о порядке их выполнения. На обычном калькуляторе можно посчитать, что есть 4х3х2х1=24 комбинации, в которых они могут сработать. А если добавить еще 4 сегмента, будет 8x7x6x5x4x3x2x1 — сорок тысяч комбинаций! Удачи в отладке 🙂

Другими словами, этот подход имеет сложность Bug O 🐞(n!). Здесь n – количество сегментов кода, изменяющих DOM. Да, это факториал. Безусловно, не все комбинации на практике могут возникнуть. С другой стороны, каждый из этих сегментов может выполняться более одного раза. Но даже с уточненным показателем Bug O сложность подобных программных интерфейсов слишком велика, можно сделать лучше.

Уменьшение отладочной сложности

Прежде всего нужно ограничить количество возможных состояний и результатов. Для этого не нужна библиотека – только продуманная структура кода.

Этот вариант не сильно отличается от предыдущего, он даже чуть более многословен. Но отлаживать его намного проще – из-за этой строки:

Очистив контейнер перед выполнением каких-либо манипуляций, вы гарантируете, что DOM-операции всегда начинаются с нуля, энтропия не увеличивается и ошибки не накапливаются.

Если вдруг появится ошибка, достаточно вернуться всего лишь на один шаг назад – к предыдущему вызову setState. Отладочная сложность такого интерфейса – 🐞(n), где n – количество сегментов, ответственных за рендеринг (тут их 4 – по количеству кейсов в switch).

Проблемы еще могут возникнуть внутри функции trySubmit, но и здесь отладка гораздо проще. Можно зарегистрировать и проверить каждое промежуточное состояние и явно запретить любые нежелательные переходы.

Конечно, постоянное сбрасывание DOM – это компромисс. Удаление и воссоздание фрагмента страницы каждый раз разрушало бы его внутреннее состояние, вызывало потерю фокуса и проблемы с производительностью в больших приложениях.

В такой момент и нужны библиотеки вроде React. Они позволяют не воссоздавать пользовательский интерфейс с нуля без необходимости.

Код может выглядеть по-другому, но принцип сохраняется. Компоненты – это абстракции. Они гарантируют, что никакой другой код не испортит DOM или состояние вашей программы. Компонентный подход помогает уменьшить отладочную сложность программных интерфейсов – Bug O.

Если в DOM что-то не так, вы можете проследить путь ошибки, просмотрев последовательно дерево компонентов. Таким образом показатель сложности равен 🐞(высота этого дерева).

Читайте также:

Размышляя о проектировании программных интерфейсов, подумайте первым делом, какова их отладочная сложность 🐞. А что насчет уже имеющихся API, с которыми вы работаете? Redux, CSS, наследование – у всего есть своя Bug O стоимость.

Оригинал: The “Bug-O” Notation

Хотите получать больше интересных материалов с доставкой?

Подпишитесь на нашу рассылку:

И не беспокойтесь, мы тоже не любим спам. Отписаться можно в любое время.




Добавить комментарий