История развития программного обеспечения

Программное обеспечение ПЭВМ. Характеристики времени выполнения конструкций языка Турбо-Паскаль.

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

Данное исследование проведено для языка Турбо-Паскаль [1–3] исходя из его широкой распространенности и наличия многих версий под различными ОС (MS-DOS, Альфа-ДОС, SCP, СР/М-80, СР/М-86, OS/2 и др.).

Методика получения временных характеристик

Для хронометрирования времени выполнения тестируемой конструкции использованы процедуры, показанные в листингах 1 и 2.

Листинг 1

procedure TMinusT1 (var H,M,S,T: integer; var H1,M1,S1,T1: integer; var RH,RM,RS,RT: integer);

begin {TMinusTl}
t1 := t1 + 100-t;
s1 := s1+59-s;
ml := ml+59-m;
hl := hl + 23-h;
if t1>=100 then begin Rt := tl-100; s1 := s1 + l end
else Rt := t1;
if s1>=60 then begin Rs := sl-60; ml := ml + l end
else Rs:= s1;
if ml>=60 then begin Rm:= ml-60; hl := hl + l end
else Rm := ml;
if hi > = 24 then Rh: = hi – 24
else Rh:= hi;
end; {TMinusTl}

Для тестирования конструкций разработана программа DORA , позволяющая определять время выполнения базовых конструкций:

циклов:
FOR I := < начало > ТО < конец > DO < оператор >;
WHILE I = < конец > DO < оператор >;
REPEAT I := I + 1 UNTIL I = < конец >;

вывода символов на экран;
конструкций:
- IF и CASE (в сравнении);
- CASE с различным числом вариантов выбора (от 1 до 9);
- арифметических операций и функций в режимах с математическим сопроцессором i 8087 и без него;
- передачи процедурам параметров простых и сложных типов (массив, запись, множество), типа указатель или запись, одно из полей которой – указатель.

Листинг 2

procedure TLStrQ ( var Hours , Minutes , Seconds , Tics : integer );
var
DosReg : Registers ;
begin { TLStrQ }
with DosReg do
begin
Ax := $2 C 00; Intr ($21, _ DosReg );
Hours : = Hi ( Cx ); { DOS возвращает часы в   СН }
Minutes := Lo ( Cx ); { Минуты в CL , }
Seconds := Hi ( Dx ); { Секунды в DH и }
Tics := Lo ( Dx ); { Сотые секунды в DL . }
end; {with}
end; {TLStrQ}

Базовые конструкции выполнялись программой DORA в цикле 30 000 раз (кроме медленных конструкций вывода на экран, которые выполнялись 1000 раз), после чего программа вычисляла время их выполнения (во всех таблицах оно дано до сотых секунды). По техническим причинам измерения проводились под MS-DOS 3.2 на ПЭВМ “СОРАМ РС-401 Turbo”, имеющей относительное быстродействие 1,1 от IBM PC XT на частоте 4,77 МГц и 1,8 – на частоте 8 МГц.

Результаты тестирования

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

    Конструкции с пустым блоком:
  1. do;
  2. do begin;
  3. procedure; begin end;
  4. begin end
  5. эквивалентны. В случае "c" дополнительное время тратится на вызов процедуры.

Более сложным является вопрос о времени передачи параметров процедурам. При увеличении числа скалярных параметров, передаваемых процедуре или функции, время увеличивается линейно, пропорционально числу передаваемых параметров (табл.1). Имеет существенное значение способ передачи параметра – по ссылке или по значению: по ссылке (VAR) параметры, кроме CHAR и INTEGER, передаются значительно быстрее.

Таблица 1.
Время передачи (в секундах) параметров в языке Турбо-Паскаль (версия 3.01А – верхняя строка, версия 4.0 – нижняя)

Параметр Число параметров
  0 1 2 3 4 5 6 7 8 9
Любой по ссылке 2,69 3,20 3,24 3,50 3,79 4,01 4,29 4,56 4,80 5,00
2,09 2,42 2,64 2,91 3,19 3,46 3,68 3,95 4,23 4,50
Integer по значению   2,97 3,18 3,47 3,63 3,90 4,11 4,34 4,56 4,77
  2,42 2,64 2,91 3,13 3,35 3,57 3,79 4,10 4,29
REAL по значению   4,60 5,33 6,76 7,96 9,34 10,65 11,67 13,29 14,56
  2,86 3,57 4,23 4,94 5,60 6,37 7,03 7,75 8,40
СНАR по значению   2,96 3,19 3,40 3,68 3,95 4,23 4,44 4,67 4,95
  2,37 2,53 2,75 2,97 3,19 3,35 3,63 3,79 4,01
STRING[1] по значению   5,44 8,18 10,93 13,67 16,37 19,11 21,80 24,56 27,29
  5,17 8,07 10,99 13,95 16,86 19,83 22,74 25,65 28,61
Pointer по значению   3,24 3,63 4,12 4,56 4,99 5,44 5,93 6,37 6,81
  2,64 3,08 3,57 4,10 4,50 4,94 5,49 5,93 6,37

Время передачи параметров типа
Type Par = Record item = < простой тип> end;
равно времени передачи параметра соответствующего простого типа, т.е. заключение переменной в запись не влияет на время ее передачи в качестве параметра.

В Турбо-Паскале при передаче по ссылке (VAR) параметра типа STRING важно, насколько заполнена эта строка. При этом в версии 3.0 быстрее всего передается целиком заполненная строка (даже быстрее, чем пустая). Это определяется способом передачи параметра через стек. Результаты приведены в табл.2. В версии 4.0 языка Турбо-Паскаль время передачи строковых параметров существенно зависит от выбранных директив компиляции. В табл. 2 данные получены при значениях директив по умолчанию и при изменении отдельных директив для версии 4.0. Из таблицы видно, что отмена контроля переполнения стека и генерации отладочной информации уменьшает время передачи параметров. Этот фактор часто недооценивается программистами.

Таблица 2
Время передачи (в секундах) строковых параметров, объявленных как 8ТК1ГЧС [5]

Фактич. Версия
длина строки

Число параметров

0        1        2        3        4        5        6        7        8        9       
Любая по ссылке 3,0 2,69 3,20 3,24 3,50 3,79 4,01 4,29 4,56 4,80 5,00

4,0

2,09 2,42 2,64 2,91 3,19 3,46 3,68 3,95 4,23 4,50

{$К-} 3,0

1,53 1,81 2,12 2,36 2,60 2,85 3,13 3,41 3,66 3,90

{$S -} 4,0

1,21 1,48 1,18 2,03 2,25 2,58 2,80 3,08 3,30 3,63

{$D -} 4,0

0,71 0,83 0,87 0,99 1,09 1,15 1,26 1,32 1,42 1,48

{$Р+} 4,0

2,26 2,58 2,80 3,13 3,35 3,68 3,90 4,12 4,40 4,67
Пустая строка
length=0
  6,37
5,10
10,00
8,02
13,62
10,87
17,25
13,73
20,93
16,58
24,56
19,56
28,24
22,41
31,80
25,21
35,48
28,18

length= 1

6,48   10,21 13,95 17,69 21,37 25,16 28,89 32,57 36,36
5,17   8,13 11,04 13,95 16,81 19,83 22,74 25,65 28,56

length = 2

6,59   10,43 14,34 18,18 22,08 25,98 29,83 33,67 37,51
5,28   8,18 11,20 14,23 17,13 20,16 23,18 26,15 29,18

length = 3

6,70   10,66 14,56 18,51 22,52 26,36 30,49 34,33 38,22
5,33   8,35 11,37 14,45 17,41 20,49 23,51Л 26,58 29,55

length =4

6,81   10,93 14,99 19,12 23,23 27,29 31,36 35,48 39,54
5,33   8,46 11,54 14,66 17,75 20,81 23,89 27,07 30,10

length =5

5,72   8,68 11,59 14,50 17,47 20,38 23,35 26,26 29,16
5,49   8,51 11,75 14,88 17,96 21,15 24,28 27,46 30,64

Примечание. $K, $S – контроль переполнения стека, $D – включение в объектный файл отладочной информации, $F – включение режима трансляции для программ объемом больше 64 Кбайт.

Время выполнения операций без математического сопроцессора (табл.3) зависит от количества цифр в числе. Результаты в таблице (<минуты>: <секунды>, <сотые>) приведены для чисел вида Х:8:6 (т.е. Y.YYYYYY). Арифметические операции над константами производятся заметно быстрее, чем над переменными. (Сравните первые строки табл.3. В остальных случаях использовались константы типа Real.)

Таблица 3
Результаты хронометрирования времени выполнения арифметических операций на ПЭВМ

Операция

Версия 3.01А

Версия 4.0

без
сопроцессора
с 
сопроцессором
без
сопроцессора
с 
сопроцессором
REAL+REAL (var) 6,17 5,38 4,81 2,90
REAL+REAL (const) 5,87 5,16 3,19 2,85
REAL+REAL 39,88 8,89 29,99 5,16
REAL+INTEGER 19,56 9,12 13,35 4,83
СОS(INTEGER) 6:17,17 18,90 5:15,27 18,13
СОS(REAL)' 6:34,48 19,77 5:20,93 19,66
LN(INTEGER) 7:40,82 13,40 6:09,87 13,41
LN(REAL) 7:44,51 13,08 6:20,30 13,51
SQR(INTEGER) 1,05 1,05 0,88 0,88
SQL(REAL) 37,73 7,31 29,77 4,78
SQRT(INTEGER) 5:14,78 8,02 4:01,12 7,41
SQRT(REAL) 5:12,96 7,52 4:03,43 7,47

Наиболее вероятные альтернативы выбора нужно располагать в начале CASE (табл.4). Время обхода этой конструкции равно времени выбора (Н + 1)-й альтернативы, где N – число альтернатив. При оптимизации времени выполнения программы следует учитывать вероятность такого исхода, и если она высока, то проверка должна осуществляться до входа в CASE.

Таблица 4
Зависимость выбора альтернативы в конструкции CASE (версия 3.0 – верхняя строка, версия 4.0 – нижняя)

Номер альтернативы 1 2 3 4 5 6 7 8 9

Время, с

1,04 1,27 1,53 1,81 2,03 2,25 2,54 2,80 2,97
0,98 1,15 1,37 1,53 1,71 1,92 2,09 2,25 2,42

В качестве альтернативы оператору САSЕ может быть использована конструкция из операторов IF. Рассмотрим два крайних варианта этой конструкции.

Первый вариант:
if X=1 then begin end;
….
if X=9 then begin end;
Второй вариант:
if Х< >1 then
  if X < >2 then
      if Х<>9 then;

Из табл. 5 видно, что операторы IF вложенные выполняются быстрее последовательно расположенных, но медленнее конструкции CASE.

Таблица 5
Зависимость времени выбора альтернативы (в секундах) в двух вариантах конструкции из операторов 1Р

Вариант Версия

Номер альтернативы

    1 2 3 4 5 6 7 8 9

Первый

3,0 1,04 1,37 1,79 2,17 2,55 2,94 3,35 3,71 4,10

4,0

0,94 1,24 1,59 1,87 2,14 2,48 2,75 3,06 3,38

Второй

3,0 1,04 1,37 1,68 1,98 2,28 2,63 2,97 3,30 3,62

4,0

0,94 1,21 1,48 1,74 1,98 2,25 2,50 2,74 3,02

В конструкции CASE перед оператором можно ставить несколько меток. В табл. 6 даны времена выполнения конструкций
следующего вида:
case < селектор > of
М1, М2, МЗ, М4, М5, Мб, М7, М8, М9: < оператор >
end; (саsе)
в зависимости от местоположения метки. Она показывает, что метки, соответствующие наиболее вероятным значениям селектора, необходимо ставить первыми.

Таблица 6
Влияние расположения меток на время выполнения конструкций

Номер метки перед вариантом 1 2 3 4 5 6 7 8 9
Время,с 0,94 1,10 1,21 1,37 1,49 1,65 1,76 1,92 2,05

Конструкции циклов FOR, WHILE и REPEAT сравнивались в описанном выше простом случае для того, чтобы можно было оценить их. Из табл. 7 видно, что в обеих версиях конструкция FOR значительно быстрее других. Однако при шаге цикла, не равном 1, программист вынужден пользоваться WHILE или REPEAT, что ведет к потере эффективности и ухудшению читаемости программы. Отсутствие в Турбо-Паскале возможности задать шаг цикла (как и операции возведения в степень) – серьезный недостаток языка, который следовало бы устранить в новых реализациях. Появление в 1989 г . версии 5.5, в которой реализованы константные выражения, символьный отладчик, объектно-ориентированное программирование и другие возможности, свидетельствует о развитии языка.

Таблица 7
Сравнение конструкций циклов (версия 3.0. – верхняя строка, версия 4.0 – нижняя)
Вид цикла FOR WHILE RЕРЕАТ
Время, с 0,60 0,90 0,85
  0,62 0,77 0,71

В табл. 8 приведены данные времени вывода на экран строк символов различной длины. Для хронометрирования брались 1000 повторений.

Таблица 8
Время вывода строки на экран (в секундах)

Частота заполнения, МГц

Длина строки, символов

1 2 3 4 5

Адаптер СGА

Версия 3.01А
4,77

1,45

4,10

6,30

8,38

10,48
8,0 0,89 2,62 3,96 5,27 6,52
Версия 4.0
4,77

0,58

1,42

1,95

2,45

2,95
8,0 0,33 0,99 1,32 1,65 1,97

Адаптер EGA

4,77
0,58 1,15 1,53 1,81 2,14
8,0 0,39 0,88 1,15 1,43 1,70

Литература

  1. Turbo Pascal version 3.0 Reference Manual. USA: Borland International, 1985. – 375 p.
  2. Turbo Pascal version 4.0 Reference Manual. USA: Borland International, 1987. –640 p..
  3. Абрамов В. Г. Система программирования Паскаль. – М.:МЦНТИ. – 1987. – Вып.51. – 102 с.

Статья поступила 15.06.1989.
Статья помещена в музей 13.04.2006 года.