                             ГЛАВА 20.

                    АВТОМАТИЧЕСКАЯ ОПТИМИЗАЦИЯ.

     Turbo Pascal производит несколько различных  типов оптимизации
кода,  начиная  от объединения констант и короткой формы вычисления
булевских выражений всех типов до отличного  редактирования связей.
Здесь описаны некоторые типы оптимизации.


                       Вычисление констант.

     Если операнды в операторе представляют собой  константы, Turbo
Pascal вычисляет выражение во время компиляции. Например,

     X := 3 + 4 * 2

     генерирует код X := 11, и

     S := 'In' + 'Out'

     генерирует код S := 'InOut'.

     Кроме того,  если операндом функций Abs,  Chr, Hi, Length, Lo,
Odd, Ord, Pred, Ptr, Round, Succ, Swap или Trunc была константа, то
функция вычисляется во время компиляции.
     Если выражением  индекса  массива  была  константа,  то  адрес
элемента  вычисляется  во  время  компиляции.  Например,  доступ  к
Data[5,5] будет  таким  же  эффективным,  как  доступ  к  отдельным
переменным.


                       Объединение констант.

     При использовании  одной  и  то  же  строковой   константы   в
операторной части 2 или более раз будет храниться только одна копия
константы. Например, два или более операторов Write('Done') в одной
и  той же операторной части будут ссылаться к одной копии строковой
константы 'Done'.


                       Короткое вычисление.

     Turbo Pascal  реализует короткую форму логического вычисления,
которое   означает,   что    вычисление    логического    выражения
останавливается,  как  только  результат всего выражения становится
очевидным.  Это гарантирует минимальное время выполнения,  и обычно
минимальный  размер  кода.  Короткая  форма  вычислений  также дает
возможность  вычисления  конструкций,   которые   иначе   были   бы
неверными; например:

     while (I <= Length(S)) and (S[I] <> ' ') do  Inc(I);
     while (P <> nil) and (P^.Value <> 5) do  P := P^.Next;

     В обоих случаях второй тест не вычисляется, если первый тест -
False.
     Кроме коротких  вычислений   существуют   полные   вычисления,
которые  выбираются  через  директиву  компилятора  {$B+}.  В  этом
состоянии  гарантируется,  что  будет   вычислен   каждый   операнд
логического выражения.


                        Порядок вычислений.

     Как разрешено в стандарном Паскале,  операнды выражения  часто
вычисляются  в порядке,  отличном от порядка в котором они записаны
(слева направо). Например, в операторе

     I := F(J) div G(J);

     где F и G - это функции типа  Integer,  G  вычисляется  до  F,
поскольку это позволяет оператору генерировать лучший код. Поэтому,
важно  помнить,  что  выражение  никогда  не  зависит  от   порядка
вычисления функций. Если в предыдущем примере F должно быть вызвано
до G, используйте временную переменную:

     T := F(j);
     I := T div G(j);

     Примечание: Как исключение из этого  правила,  когда  включены
короткие вычисления ({$B-}) логические операнды,  сгруппированные с
and или or, всегда вычисляются слева направо.


                        Проверка диапазона.

     При присваивании    константы   переменной   и   использовании
константы как параметра значения,  проверка на диапазон делается во
время компиляции;  ошибка  времени выполнения выхода за диапазон не
генерируется.  Например,  Х := 999,  где X типа Вyte выдает  ошибку
времени компиляции.


                      Сдвиг вместо умножения.

     Операция X*C,  где С -  константа  в  степени  2,  кодируется,
используя  инструкцию  SHL.  Кроме  того,  когда  размер  элементов
массива  кратен  степени  2,   для   вычисления   индекса   массива
используется инструкция SHL (а не MUL).


                   Автоматическое выравнивание.

     По умолчанию  Turbo  Pascal  выравнивает  все   переменные   и
типированные  константы  длиной  более 1 байта на границу машинного
слова.  На всех 16-ти битовых процессорах  80х86,  выравнивание  на
слово  работает  значительно быстрее,  поскольку доступ к элементам
длиной в слово,  находящихся на четных адресах происходит  быстрее,
чем на нечетных.
     Выравнивание данных управляется  через  директиву  компилятора
$A.  По  умолчанию  в  состоянии  {$A+}  переменные  и типированные
константы  выравниваются  как  описано  выше.  В  состоянии   {$A-}
выравнивания не производится.  Подробную информацию см.  в главе 21
"Директивы компилятора".


                 Удаление неиспользованного кода.

     Операторы, которые никогда не выполняются, не генерируют кода.
Например, эти конструкции не будут генерировать код:

     if False then  оператор
     while False do  оператор


                  Отличное редактирование связей.

     Встроенный редактор связей Turbo Pascal  автоматически удаляет
неиспользованный код и данные при построении .EXE файла. Процедуры,
функции, переменные и типированные константы - которые присутствуют
в программе,  но никогда не используются,  удаляются из .EXE файла.
Удаление неиспользуемого кода производится на попроцедурной основе,
а удаление неиспользованнных данных - на основе раздела объявления.
     Рассмотрим следующую программу:

     program SmartLink;
     const
        H: array[0..15] of Char = '0123456789ABCDEF';
     var
        I, J: Integer;
        X, Y: Real;
     var
        S: String[79];
     var
        A: array[1..10000] of Integer;

     procedure P1;
     begin
        A[1] := 1;
     end;

     procedure P2;
     begin
        I := 1;
     end;

     procedure P3;
     begin
        S := 'Turbo Pascal';
        P2;
     end;

     begin
        P3;
     end.

     Главная программа вызывает P3, которая вызывает P2, и обе P2 и
P3 включены в .EXE файл;  поскольку P2 ссылается  в  первую  секцию
объявления var,  и P3 сылается во вторую секцию объявления var,  то
I,  J,  X, Y, S также будут включены в .EXE файл. Однако, поскольку
нет ссылок к P1, H и A, эти объекты удаляются.
     Отличное редактирование   связей,    особенно    удобно    при
использовании  модулей,  реализующих  библиотеки  процедур/функций.
Примером такого модуля является стандартный модуль DOS: он содержит
ряд процедур и функций, которые редко используются одной программой
одновременно.  Если  программа  использует  только  одну  или   две
процедуры  DOS,  то только эти процедуры включаются в .EXE файл,  а
все остальные удаляются, значительно сокращая размер .EXE файла.
