Файл: Руководство по стилю программирования и конструированию по.pdf
ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 30.11.2023
Просмотров: 878
Скачиваний: 2
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
СОДЕРЖАНИЕ
ГЛАВА 26 Методики оптимизации кода
627
var index: integer;
lowerByte: byte;
upperByte: byte;
targetIndex: integer;
begin targetIndex := 1;
for index := 1 to byteCount do begin target[ targetIndex ] := ( (source[ index ] and $F0) shr 4 ) + $41;
target[ targetIndex+1 ] := (source[ index ] and $0f) + $41;
targetIndex := targetIndex + 2;
end;
end;
Трудно увидеть жир в этом коде, однако он содержит много манипуляций с бита- ми, что не является сильной стороной Delphi. А вот ассемблер подходит для это- го как нельзя лучше, так что этот код является хорошим кандидатом на перепи- сывание. Вот что получается в итоге:
Пример метода, переписанного на ассемблере
procedure HexExpand(
var source;
var target;
byteCount : Integer
);
label
EXPAND;
asm
MOV ECX,byteCount // Загрузка числа расширяемых байт.
MOV ESI,source // Смещение источника.
MOV EDI,target // Смещение приемника.
XOR EAX,EAX // Обнуление индекса смещения в массиве.
EXPAND:
MOV EBX,EAX // Смещение в массиве.
MOV DL,[ESI+EBX] // Получение байта источника.
MOV DH,DL // Копирование байта источника.
AND DH,$F // Получение старших разрядов.
ADD DH,$41 // Преобразование символа в верхний регистр.
SHR DL,4 // Сдвиг разрядов на нужную позицию.
AND DL,$F // Получение младших разрядов.
ADD DL,$41 // Преобразование символа в верхний регистр.
SHL BX,1 // Удвоение смещения в массиве-приемнике.
MOV [EDI+EBX],DX // Копирование слова в приемник.
628
ЧАСТЬ V Усовершенствование кода
INC EAX // Увеличение индекса смещения в массиве.
LOOP EXPAND // Повторение цикла.
end;
Переписывание этого кода на ассемблере привело к уменьшению времени выпол- нения на 41%. Логично предположить, что код, написанный на языке, более под- ходящем для операций над битами, (скажем, на C++), менее восприимчив к этому виду оптимизации, чем код Delphi. Проверим:
Время выполнения
Время выполнения
Экономия
Язык
высокоуровневого кода
ассемблерного кода
времени
C++
4,25 3,02 29%
Delphi
5,18 3,04 41%
Второй столбец этой таблицы отражает эффективность двух языков в отношении операций над битами. После оптимизации время выполнения стало почти оди- наковым — перевод кода на ассемблер свел к минимуму первоначальные разли- чия между Delphi и C++.
Полученный нами метод показывает, что результатом переписывания кода на ас- семблере не всегда является огромный и уродливый метод. Итоговый код часто оказывается довольно компактным. Иногда ассемблерный код почти так же ком- пактен, как его высокоуровневый эквивалент.
Существует одна относительно легкая и эффективная стратегия переписывания кода на ассемблере. В самом начале воспользуйтесь компилятором, генерирую- щем ассемблерные листинги во время компиляции. Извлеките ассемблерный код метода, который вам нужно оптимизировать, и сохраните его в отдельном исходном файле. Используя этот код как основу, выполните оптимизацию вручную, прове- ряя корректность кода и оценивая улучшения на каждом этапе. Некоторые ком- пиляторы вставляют в ассемблерный код высокоуровневые операторы в форме комментариев. Если ваш компилятор на это способен, можете сохранить перво- начальные операторы в ассемблерном коде в качестве документации.
Контрольный список: методики оптимизации кода
Улучшение и быстродействия, и объема
Замените сложную логику на обращения к таблице.
Объедините циклы.
Используйте целочисленные переменные вместо переменных с плавающей запятой.
Инициализируйте данные во время компиляции.
Используйте константы корректного типа.
Вычислите результаты предварительно.
Устраните часто используемые подвыражения.
Перепишите ключевые методы на низкоуровневом языке.
Улучшение только быстродействия
Прекращайте проверку сразу же после получения ответа.
Упорядочивайте тесты в блоках case и цепочках операторов if-then-else по частоте.
http://cc2e.com/2672
ГЛАВА 26 Методики оптимизации кода
629
Сравните быстродействие похожих структур логики.
Используйте методику отложенных вычислений.
Разомкните цикл, содержащий оператор if.
Выполните развертывание цикла.
Минимизируйте объем работы, выполняемой внутри цикла.
Используйте сигнальные значения в циклах поиска.
Вложите более ресурсоемкий цикл в менее ресурсоемкий.
Снизьте стоимость операций, выполняемых внутри цикла.
Замените многомерные массивы на одномерные.
Минимизируйте число обращений к массивам.
Дополните типы данных индексами.
Кэшируйте часто используемые значения.
Проанализируйте алгебраические тождества.
Снизьте стоимость логических и математических выражений.
Остерегайтесь системных методов.
Встройте методы.
26.7. Если что-то одно изменяется,
что-то другое всегда остается постоянным
Трудно не согласиться с тем, что за 10 лет, прошедших со времени первого изда- ния этой книги, некоторые параметры производительности систем изменились.
Компьютеры стали гораздо быстрее, а объем памяти вырос во много раз. Работая над первым изданием, для получения выразительных измеримых результатов я выполнял большинство тестов этой главы от 10 000 до 50 000 раз. При подготов- ке этого издания мне пришлось выполнять большинство тестов от 1 до 100 млн раз. Если для получения измеримых результатов тест нужно выполнить 100 млн раз, стоит задуматься над тем, заметит ли хоть кто-нибудь последствия выполненной оптимизации в реальной программе. Компьютеры стали столь мощными, что для многих распространенных типов программ виды оптимизации, описанные в этой главе, стали нерелевантными.
В то же время другие аспекты производительности совсем не изменились. Воз- можно, программистов, создающих приложения для настольных ПК, вопросы оптимизации уже почти не тревожат, но разработчики программ для встроенных систем, систем, работающих в реальном времени, и других систем, обладающих ограниченными ресурсами, все еще должны владеть методиками оптимизации кода.
Необходимость оценки результатов каждой попытки оптимизации кода не теряет актуальности с 1971 г., когда Дональд Кнут опубликовал свое исследование программ
Fortran. Судя по данным, приведенным в этой главе, результаты отдельных видов оптимизации на самом деле сейчас
менее предсказуемы, чем 10 лет назад. Они за- висят от языка, компилятора, и его версии, используемых библиотек, их версий,
параметров компилятора и многого другого.
Оптимизация кода неизбежно подразумевает нахождение компромисса между сложностью, удобочитаемостью, простотой и удобством сопровождения програм- мы, с одной стороны, и желанием повысить производительность — с другой. Не-
630
ЧАСТЬ V Усовершенствование кода обходимое при оптимизации перепрофилирование кода приводит к значитель- ному росту затрат на сопровождение программы.
Есть один хороший способ сопротивления соблазну преждевременной оптимиза- ции и содействия созданию ясного и простого кода: требуйте, чтобы оптимизация приводила к
измеримому улучшению. Если оптимизация оправдывает профилиро- вание кода и оценку результатов, наверное, ее следует выполнить, если будет пока- зано, что она работает. Но если оптимизация не оправдывает проведения профи- лирования, она не может оправдать ухудшения удобочитаемости, удобства сопро- вождения и других характеристик кода. Влияние неоцененной оптимизации кода на производительность в лучшем случае может быть только теоретическим, тогда как ее влияние на удобочитаемость столь же определенно, сколь пагубно.
Дополнительные ресурсы
По-моему, лучшая работа по оптимизации кода —
Writing
Efficient Programs (Bentley, Englewood Cliffs, NJ: Prentice Hall,
1982). Это довольно старая книга, и все же постарайтесь ее найти. В ней вы найдете экспертное обсуждение общих вопросов оптимизации кода. Бентли описывает методики обмена времени на пространство и простран- ства на время, а также приводит несколько примеров перепроектирования типов данных, позволяющего и ускорить код, и сделать его компактнее. Подход Бентли чуть более описателен, чем тот, что принял я, но приведенные им случаи весьма интересны. Бентли проводит несколько методов через несколько этапов оптими- зации, позволяя увидеть результаты первой, второй и третьей попыток. Описание главной идеи занимает 135 страниц. Эта книга отличается необычайно высоким отношением «сигнал/шум», что делает ее одним из редких бриллиантов, которые следует иметь каждому практикующему программисту.
В приложении 4 книги Бентли
Programming Pearls, 2d ed. (Bentley, Boston, MA:
Addison-Wesley, 2000) вы можете найти резюме правил оптимизации кода, опи- санных в его более ранней книге.
Кроме того, есть целый ряд книг, в которых вопросы опти- мизации рассматриваются в контексте конкретных техно- логий. Некоторые из них перечислены ниже, а самый све- жий список вы найдете на Web-странице, адрес которой указан слева.
Booth, Rick.
Inner Loops: A Sourcebook for Fast 32-bit Software Development. Boston,
MA: Addison-Wesley, 1997.
Gerber, Richard.
Software Optimization Cookbook: High-Performance Recipes for the Intel
Architecture. Intel Press, 2002.
Hasan, Jeffrey and Kenneth Tu.
Performance Tuning and Optimizing ASP.NET Applica-
tions. Berkeley, CA: Apress, 2003.
Killelea, Patrick.
Web Performance Tuning, 2d ed. Sebastopol, CA: O’Reilly & Associates,
2002.
Larman, Craig and Rhett Guthrie.
Java 2 Performance and Idiom Guide. Englewood Cliffs,
NJ: Prentice Hall, 2000.
http://cc2e.com/2679
http://cc2e.com/2686
1 ... 72 73 74 75 76 77 78 79 ... 104
ГЛАВА 26 Методики оптимизации кода
631
Shirazi, Jack.
Java Performance Tuning. Sebastopol, CA: O’Reilly & Associates, 2000.
Wilson, Steve and Jeff Kesselman.
Java Platform Performance: Strategies and Tactics.
Boston, MA: Addison-Wesley, 2000.
Ключевые моменты
쐽
Результаты конкретных видов оптимизации во многом зависят от языка, ком- пилятора и среды. Не оценив результатов оптимизации, вы не сможете сказать,
помогает она программе или вредит.
쐽
Первый вид оптимизации часто далеко не самый лучший. Обнаружив эффек- тивный вид оптимизации, продолжайте пробовать и, возможно, найдете еще более эффективный.
쐽
Оптимизация кода похожа на ядерную энергию — это противоречивая и эмо- циональная тема. Кто-то считает, что оптимизация настолько ухудшает надеж- ность и удобство сопровождения программы, что ее вообще выполнять не следует. Другие думают, что при соблюдении должной предосторожности она приносит пользу. Если вы решите использовать методики, описанные в этой главе, будьте внимательны и осторожны.
ГЛАВА 25 Стратегии оптимизации кода
633
Часть VI
СИСТЕМНЫЕ ВОПРОСЫ
쐽
Глава 27. Как размер программы влияет на конструирование
쐽
Глава 28. Управление конструированием
쐽
Глава 29. Интеграция
쐽
Глава 30. Инструменты программирования
634
ЧАСТЬ VI Системные вопросы
Г Л А В А 2 7
Как размер программы
влияет на конструирование
Содержание
쐽
27.1. Взаимодействие и размер
쐽
27.2. Диапазон размеров проектов
쐽
27.3. Влияние размера проекта на возникновение ошибок
쐽
27.4. Влияние размера проекта на производительность
쐽
27.5. Влияние размера проекта на процесс разработки
Связанные темы
쐽
Предварительные требования к конструированию: глава 3
쐽
Определение вида ПО, над которым вы работаете: раздел 3.2
쐽
Управление конструированием: глава 28
Масштабирование в области разработки ПО — это не просто вопрос увеличения составных частей небольшого проекта. Допустим, вы разработали программный комплекс Gigatron, содержащий 25 000 строк кода, за 20 человеко-месяцев и на- шли 500 ошибок во время производственного тестирования. Допустим, Gigatron
1.0 имел успех, так же, как и Gigatron 2.0, и вы начали работу над Gigatron Deluxe
— значительно улучшенной версией программы, которая предположительно бу- дет состоять из 250 000 строк кода.
Хотя ее размер в 10 раз превышает размер начальной версии, Gigatron Deluxe по- требует не 10-кратных усилий при разработке, а 30-кратных. Более того, 30-крат- ные общие затраты не означают 30-кратных затрат только на конструирование.
Возможно, потребуется потратить в 25 раз больше усилий на конструирование, и в
40 — на архитектуру и системное тестирование. Точно так же вы не получите
10-кратный прирост ошибок — он может быть 15-кратным и даже больше.
Если вы привыкли работать над маленькими проектами, то ваш первый проект среднего или большого размера может вырваться из-под контроля, превратившись в необузданного зверя, вместо благоприятного исхода, который вы себе представ- ляли. Эта глава рассказывает, какие виды хищников можно встретить и где найти хлыст и кольцо для их укрощения. С другой стороны, если вы привыкли работать http://cc2e.com/2761