YouIT

Как писать быстродействующий код: Часть 1

551   0   2   0 | Добавлено 147 дней назад  

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


Контроль объема аллокаций в управляемую кучу

Несмотря на факт наличия сборщиков мусора на всех современных платформах разработки, программисту все равно необходимо думать об аллокациях. Да, программист больше не должен явно освобождать память от созданных им объектов, как было в С++. Однако, бездумно тоннами аллоцировать объекты в управляемую кучу также не вариант, так как вы создадите серьезную нагрузку на сборщик мусора, в результате чего быстродействие вашего приложения может просесть.

Аллокации в управляемую память условно могут быть классифицированы на явные и неявные. Явные аллокации - это когда программист осознанно своими руками создает большое количество объектов. В таких случаях можно задуматься, например, об их кешировании с использованием шаблонов Приспособленец (Flyweight) или Пул объектов (Object Pool).

Неявные аллокации - это когда программист использует некоторую программную конструкцию, под капотом которой происходят аллокации. Речь идет об активной работе с неизменяемыми типами данных (например, string), об использовании механизма Замыкания (Clojures) и других. От неявных аллокаций программиста может спасти в целом хорошее знание используемого языка программирования, а в частности тема управления памятью. Для ознакомления с конкретными операциями, которые приводят к аллокациям в вашем языке программирования, проведите исследование в Google по следующему поисковому запросу:

"<Ваш язык программирования здесь> memory management"

Использование кеширования в приложении

Кеширование является невероятно обширной темой, которая достойна целой книги. Задача кеширования - заставить ваше приложение работать быстрее путем уменьшения количества запросов от клиента к источнику данных. Кеширование может выполняться на большом количестве уровней, начиная от баз данных и заканчивая браузером. Веб программист обычно применяет кеширование на уровне приложения (бекенд) и на уровне клиента (браузера). На уровне приложения программист кеширует данные, прочитанные из базы данных. На уровнае клиента обычно кешируются статические .js и .css файлы, но могут кешироваться и динамические редко модифицируемые данные с целью уменьшения количества запросов на веб-сервер.

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

Вы можете начать знакомство с кешированием на стороне бекенда со следующих шаблонов: Приспособленец (Flyweight), Пул объектов (Object Pool), а также шаблона Cache-aside.

Знание структур данных

В программировании существует большое разнообразие структур данных. Самой простой структурой является Массив, который имеет фиксированную длину с возможностью обращаться к его элементам по индексу. Чуть более сложными являются такие структуры данных как Стек, Очереди, Списки, Хеш-таблица, Множества, Деревья, Графы, а также многочисленные подвиды многих перечисленных структур. Такое разнообразие доступно программисту по одной простой причине - каждая структура данных оптимизирована под конкретный вид задач. Если формулировать точнее, то любая задача может быть решена при помощи любой структуры данных. Однако от выбора вами структуры данных наобум может серьезно просесть быстродействие вашего кода.

Простой пример: вам необходимо хранить в памяти последовательность некоторых элементов, в которую часто необходимо добавлять новые элементы. Вы можете решить данную задачу при помощи Массива. Однако массивы имеют одну особенность: размер массивов определяется на стадии компиляции программы и не может быть изменен во время ее выполнения. То есть вы сможете "добавлять" в массив новые элементы, постоянно пересоздавая массив при каждой вставке нового элемента. Решает ли Массив поставленную задачу? Да. Решает ли массив поставленную задачу оптимально? Нет.

Каждая структура данных имеет свои достоинства и недостатки: например, к элементам массива можно обратиться по индексу, но вставка нового элемента невозможна; в односвязный или двусвязный списки можно вставить новый элемент за константное время, но поиск конкретного элемента осуществляется только полным перебором; хеш-таблица позволяет быстро доступиться к элементу по ключу, но обращение по индексу не поддерживается. Выбирая структуру данных, сопоставьте ваши требования с достоинствами и недостатками имеющихся в вашем распоряжении структур данных и сделайте выбор в пользу максимально соответствующей единицы.

Знание алгоритмов

C алгоритмами тут все очень похоже на структуры данных. Большинство задач может быть решено при помощи очень простых алгоритмов, освоение которых не займет у вас много времени. Отсортировать любой массов можно при помощи пузырьковой сортировки. Для поиска объекта в Бинарном дереве, можно конвертировать дерево в список и воспользоваться простым перебором, то есть Линейным поиском. Однако такие примитивные подходы могут эффективно работать только на небольшом количестве данных. На больших коллекциях простые алгоритмы будут выполняться медленно.

Хороший алгоритм требует минимум процессорного времени и эффективно распоряжается оперативной памятью. Алгоритмы тесно связаны со структурами данных. Большая часть алгоритмов выполняется непосредственно на структурах данных. К алгоритмам, знание которых могут улучшить производительность вашего кода, относятся Бинарный поиск, Поиск в глубину, Поиск в ширину, Алгоритмы сортировок (Быстрая сортировка, Сортировка слиянием) и другие.

Умеренная нормализация баз данных

С понятием Нормализация и Нормальные формы программисты обычно сталкиваются еще в самом начале изучения реляционных баз данных. Первая нормальная форма говорит о необходимости хранить в ячейке только атомарное значение, вторая - о зависимости всех колонок от первичного ключа, третья - об отсутствии транзитивных зависимостей и так далее. Нормализация является важной фундаментальной концепцией, которая позволяет уменьшить избыточность (дублирование) данных. Однако нормализация не лишена недостатков, одним из которых является уменьшение скорости выполнения SELECT запросов. Следование нормальным формам непременно ведет, например, к появлению большего количества таблиц, соединение которых операторами INNER JOIN, LEFT JOIN и другими будет негативно влиять на производительность приложения.

Решить проблему с производительностью можно при помощи Денормализации. Простыми техниками денормализации являются: 1) объединение нескольких связанных таблиц в одну, 2) предварительное вычисление значений и сохранение их в отдельных колонках.

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

Используйте Нормализацию когда: 1) Ваше приложение часто обновляет данные в базе данных; 2) Целостность данных критична для вашего приложения (например, банковская сфера) 3) К вашему приложению не предъявляются высокие требования по быстродействию.

Используйте Денормализацию когда: 1) Ваше приложение редко обновляет данные в базе данных, но часто их читает; 2) Целостность данных не критична для вашего приложения (например, блог) 3) Вы применили уже все другие техники оптимизации производительности (оптимизация запросов, создание индексов, кеширование), но не достигли желаемого результата.

Во второй части статьи мы разберем вторую пятерку рекомендаций по созданию быстрых программ. Подписывайтесь в группы Телеграм, Фейсбук и ВКонтакте, чтобы ничего не пропустить.


Похожие статьи

Комментарии (0)

Авторизируйтесь для участия в дискуссии

Google Facebook ВКонтакте
работа программиста качество кода IT-компания обучение программированию карьера собеседование C# сертификация джуниор алгоритмы ООП энтерпрайз .NET тестирование javascript программирование эстимейты roadmaps информатика фан быстродействие базы данных