Стандарты программирования на С++. 101 правило и рекомендация | страница 18



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

Данный совет состоит из двух частей. Во-первых, даже до того, как станет известно, будут ли объемы данных достаточно велики, чтобы для конкретных вычислений возникла проблема, по умолчанию следует избегать использования алгоритмов, которые работают с пользовательскими данными (которые могут расти), но не способны к масштабированию, если только использование менее масштабируемого алгоритма не приводит к существенному повышению понятности и удобочитаемости кода (см. рекомендацию 6). Но все мы часто сталкиваемся с сюрпризами. Мы пишем десять фрагментов кода, думая, что они никогда не будут иметь дела с большими наборами данных. И это действительно оказывается так — в девяти случаях из десяти. В десятом случае мы сталкиваемся с проблемами производительности. Это не раз случалось с нами, и мы знаем, что это случалось (или случится) и с вами. Конечно, мы вносили исправления и передавали их потребителям, но лучше было бы избежать таких затруднений и выполнения лишней работы. Так что при прочих равных условиях (включая понятность и удобочитаемость) воспользуйтесь следующими советами.

• Используйте гибкие динамически распределяемые данные вместо массивов фиксированного размера. Массив "больший, чем наибольший массив, который мне когда-либо потребуется" приводит к ошибкам и нарушению безопасности (см. рекомендацию 77). Массивы можно использовать только тогда, когда размеры данных фиксированы и известны во время компиляции.

• Следует точно знать сложность используемого алгоритма. Не забывайте о такой ловушке, как линейный алгоритм, который вызывает другую линейную операцию, что в результате делает алгоритм квадратичным (см., например, рекомендацию 81).

• По возможности используйте линейные или более быстрые алгоритмы. Идеальны алгоритмы с константной сложностью, такие как >push_back или поиск в хэш-таблице (см. рекомендации 76 и 80). Неплохи алгоритмы со сложностью O(log N), такие как операции с контейнерами >set/>map и