Иллюстрированный самоучитель по практике программирования

Настройка кода

Если цикл более длинный, тот же тип преобразования можно применить для уменьшения количества операций:

Иллюстрированный самоучитель по практике программирования › Производительность › Настройка кода

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

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

Много лет назад мы писали программу просмотра текста для вывода на печать; в этой программе специальные символы, вроде %, приходилось выбирать из специальной таблицы. Измерения показали, что по большей части специальные символы использовались для рисования линий (строк), состоящих из многократного повторения одного и того же символа. Кэширование только одного последнего использованного символа серьезно улучшило быстродействие программы при обработке типичного ввода.

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

drawchar(c);

В исходной версии drawchaг осуществлялся вызов show(lookup(c)). В реализации с кэшированием для запоминания последнего вызванного символа и его кода использовались внутренние статические переменные:

Иллюстрированный самоучитель по практике программирования › Производительность › Настройка кода

Напишите специальную функцию захвата памяти (аллокатор).
Довольно часто единственной горячей точкой программы с точки зрения быстродействия является захват памяти, который проявляется в огромном количестве обращений к malloc или new. Когда по большей части запрашиваются блоки одного размера, то можно существенно ускорить программу, заменив вызовы общего аллокатора вызовами специализированной подпрограммы. Такой специальный аллокатор один раз вызывает malloc, получая большой массив элементов, а потом "выдает" их по одному; в результате получается более дешевая операция. Освобождаемые элементы помещаются обратно в список свободных элементов (free list), благодаря чему их можно сразу же использовать снова.

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

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

Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.