Категории
Самые читаемые
ChitatKnigi.com » 🟢Компьютеры и Интернет » Программное обеспечение » UNIX — универсальная среда программирования - Брайан Керниган

UNIX — универсальная среда программирования - Брайан Керниган

Читать онлайн UNIX — универсальная среда программирования - Брайан Керниган
1 ... 70 71 72 73 74 75 76 77 78 ... 103
Перейти на страницу:

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать

8.7 Оценка времени выполнения

Мы сравнивали hoc с другими программами-калькуляторами UNIX, чтобы приблизительно оценить, насколько хорошо он работает. К таблице, представленной ниже (табл. 8.1), можно, конечно, отнестись скептически, но она показывает "разумность" нашей реализации. Все приведенные в ней величины даны в секундах. Работа велась на PDP-11/70. Было выполнено два теста. Первый, вычисление функции Аккерманна ack(3,3), — хороший тест для отработки механизма вызова функций. Здесь происходят 2432 вызова, причем некоторые из них достаточно глубоко вложены.

func ack() {

 if ($1 == 0) return ($2+1)

 if($2 == 0) return (ack($1 - 1, 1))

 return (ack($1 - 1, ack($1, $2 - 1)))

}

ack(3,3)

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

proc fib() {

 a = 0

 b = 1

 while (b < $1) {

  с = b

  b = a+b

  a = c

 }

}

i = 1

while (i < 100) {

 fib(1000)

 i = i + 1

}

Тест выполнялся на четырех языках: hoc, bc(1), bas (древний диалект Бейсика, который существует только на PDP-11) и Си (использовался тип PDP-11 для всех переменных) .

Числа, приведенные в табл. 8.1, являются суммой пользовательского и системного времени процессора и вычислены с помощью функции time.

Программа (3,3) 100*fib(1000) hoc 5.5 5.0 bas 1.3 0.7 bc 39.7 14.9 c <0.1 0.1

Таблица 8.1: Время работы на PDP-11/70 (в секундах)

Можно также приспособить Си программу для определения количества времени, используемого каждой функцией. Программу нужно перетранслировать в режиме профилирования, введя флаг -p в каждой единице трансляции Си и при режиме загрузки. Если изменить файл makefile для чтения:

hoc6: $(OBJS)

      сс $(CFLAGS) $(OBJS) -lm -о hoc6

чтобы команда сс задействовала переменную CFLAGS, а затем задать

$ make clean; make CFLAGS=-p

то результирующая программа будет выполняться с профилированием. После выполнения программы остается файл mon.out, который интерпретируется программой профилировщиком prof.

Для иллюстрации изложенного мы протестировали hoc6 на приведенной выше программе Фибоначчи:

$ hoc6 <fibtest       Запуск теста

$ prof hoc6 | sed 15q Анализ

name   %time cumsec #call ms/call

_pop    15.6 0.85   32182  0.03

_push   14.3 1.63   32182  0.02

mcount  11.3 2.25

csv     10.1 2.80

cret     8.8 3.28

_assign  8.2 3.73    5050  0.09

_eval    8.2 4.18    8218  0.05

_execute 6.0 4.51    3567  0.09

_varpush 5.9 4.83   13268  0.02

_lt      2.7 4.98    1783  0.08

_constpu 2.0 5.09     497  0.22

_add     1.7 5.18    1683  0.05

_getarg  1.5 5.26    1683  0.05

_yyparse 0.6 5.30       3 11.11

$

Результаты, полученные с помощью профилировщика, также подвержены случайным вариациям, как и те, что получены с помощью функции time, поэтому их следует считать лишь указанием настоящих значений, а не принимать за абсолютную истину. Тем не менее при необходимости приведенные значения могут помочь повысить быстродействие программы hoc. Приблизительно третья часть времени тратится на запись и чтение из стека. Накладные расходы еще более возрастут, если мы будем учитывать время выполнения функций связи csv и cret между программами Си (функция mcount представляет собой часть программы с профилированием, полученную с помощью команды ее -р.). Замена вызовов функций на макрообращения даст заметную разницу во времени выполнения.

Для проверки этого предположения мы изменили code.c, заменив вызовы push и pop на макрокоманды, управляющие стеком:

#define push(d) *stackp++ = (d)

#define popm() *--stackp = pop() /* функция все-таки нужна */

(Функция pop все-таки нужна в качестве кода операции нашей машины, поэтому нельзя заменить все обращения к ней.) Новая версия выполняется на 35% быстрее; время в табл. 8.1 сокращается от 5.5 до 3.7 с и от 5.0 до 3.1 с.

Упражнение 8.22

В макрокомандах push и popm не предусмотрен контроль ошибок. Прокомментируйте разумность такого решения. Как бы вы обеспечили контроль ошибок, производимый в версии с функциями, не снижая быстродействия макрокоманд?

8.8 Заключение

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

Во-вторых, и это уже философский аспект, ценна сама постановка задачи речь идет о разработке языка, а не просто о написании программы. Построение программы как языкового процессора обеспечивает регулярность синтаксиса (т.е. взаимодействие с пользователем), делает более структурированной реализацию. Кроме того, мы получаем гарантию, что новые средства будут хорошо согласовываться с уже реализованными. Под "языками", конечно, следует понимать не только традиционные языки программирования, но и уже упоминавшиеся выше в примерах языки eqn и pick, а также yacc, lex, и make.

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

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

Хотелось бы отметить, что из-за ограниченного объема книги мы мало внимания уделили тем средствам UNIX, которые применяются при разработке семейства программ hoc. Каждая версия программы находится в отдельном каталоге, для идентичных файлов используются связи; постоянно вызываются команды ls и du, чтобы следить за тем, какие файлы где находятся. На многие вопросы ответы дают сами программы. Например, на вопрос: "Где описана данная переменная?" отвечает программа grep. "Как мы внесли изменения в данную версию?" отвечает idiff. "Насколько велик файл?" отвечает wc. Пора делать копию файла обратитесь к команде cp. Нужно скопировать только те файлы, которые изменились со времени последнего копирования? Вам поможет в этом деле программа make.

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

Историческая и библиографическая справка

Программа yacc создана С. Джонсоном. Класс языков, для которых yacc может создавать программу разбора, называется LALR-(1): разбор здесь ведется слева направо и входной поток просматривается не более чем на одну лексему вперед. Понятие раздельных описаний для задания приоритетов и разрешения неоднозначностей в грамматике появилось вместе с yacc. Этот вопрос рассматривается в статье А. В. Ахо, С. К. Джонсона и Д. Д. Ульмана "Deterministic parsing of ambiguous grammars" (CACM, August, 1975). Там же приведены новые алгоритмы и структуры данных для создания и хранения таблиц разбора.

Основы теории, на базе которой построены yacc и другие программы анализаторы, излагаются в книге А. В. Ахо и Д. Д. Ульмана "Principles of Compiler Design" (Addison Wesley, 1977). Сама программа yacc описана в справочном руководстве по UNIX (том 2B). В этом разделе также представлен калькулятор, сравнимый с hoc2: для вас такое сравнение может оказаться полезным.

1 ... 70 71 72 73 74 75 76 77 78 ... 103
Перейти на страницу:
Открыть боковую панель
Комментарии
Настя
Настя 08.12.2024 - 03:18
Прочла с удовольствием. Необычный сюжет с замечательной концовкой
Марина
Марина 08.12.2024 - 02:13
Не могу понять, где продолжение... Очень интересная история, хочется прочесть далее
Мприна
Мприна 08.12.2024 - 01:05
Эх, а где же продолжение?
Анна
Анна 07.12.2024 - 00:27
Какая прелестная история! Кратко, ярко, захватывающе.
Любава
Любава 25.11.2024 - 01:44
Редко встретишь большое количество эротических сцен в одной истории. Здесь достаточно 🔥 Прочла с огромным удовольствием 😈