Замечание

Программа выводит отсчет о точности таймера:

Resolution: 8.39e-07

0 ms. , actual time = 0.024674 seconds.

100 ms. , actual time = 0.127362 seconds.

200 ms. , actual time = 0.222327 seconds.

300 ms. , actual time = 0.314453 seconds.

400 ms. , actual time = 0.393548 seconds.

500 ms. , actual time = 0.465171 seconds.

600 ms. , actual time = 0.630901 seconds.

700 ms. , actual time = 0.738385 seconds.

800 ms. , actual time = 0.775155 seconds.

900 ms. , actual time = 0.836996 seconds.

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

Создание класса измерения производительность

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

Листинг 3.1 BENCH.H

(объявление класса TBench)

1: // bench.h – Объявление класса TBench

2:

3: #ifndef__ BENCH_H

4: #define__ BENCH_H 1

// Предотвращение нескольких #include

5:

6: #include <classlib\timer.h>

7:

8: typedef void ( * testfn) (void);

9:

10: class TBench: public TTimer {

11: public;

12: TBench(): TTimer() {}

13: void Benchmark(long numTests, testfn tf);

14: void Report(void);

15: };

16:

17: #endif // __ BENCH_H

 

Класс TBench выводится из TTimer. Конструктор TBench() (строка 12) вызывает конструктор базового класса TTimer, но не выполняет никаких новых операторов для конструирования объекта TBench. Функция-член Benchmark() (строка 13) имеет два параметра – numTests, равный числу тестов, которые необходимо выполнить, и tf, ссылающийся на тестируемую функцию, которая должна иметь тип void и не должна иметь параметров (см. typedef в строке 8). Вторая функция-член Report(), определенная в строке 14, отображает результат теста.

В листинге 3.2 приводится реализация производного класса TBench. Следующая программа демонстрирует использование этого модуля, поэтому не компилируйте его пока.

Листинг 3.2 BENCH.CPP

(реализация класса TBench)

1: // bench.cpp -- реализация класса TBench

2:

3: #include <stdio.h>

4: #include “bench.h”

5:

6: //вызывает тестируемую функцию tf numTests раз

7: void TBench:: Benchmark(long numTests, testfn tf)

8: {

9: printf(“Running %1d tests…”, numTests);

10: Reset(); // Reset timer to zero

11: Start(); // Start timing

12: While (--numTests >= 0)

13: (* tf) (); // call user test function

14: Stop(); // stop timing

15: puts(“\nTests completed”);

16: }

17:

18: // Выводит результаты теста

19: void TBench::Report(void)

20: {

21: double result = Time();

22: if (result < Resolution())

23: puts(“Results too small for accuracy”);

24: printf(“Elapsed time == %6f sec. \n”, result);

25: }

 

В строках 7-16 реализуется функция-член Benchmark(). После отображения числа выполняемых тестов, функция сбрасывает и запускает таймер с помощью вызова наследованных функций-членов Reset() и Star().

В строках 12-13 вызывается необходимое число раз тестируемая функция, адрес которой хранится в указателе tf . после завершения последнего теста в строке 14 вызывается еще одна наследованная функция-член Stop(), прерывающая отсчет времени. В строке 15 выводится которое сообщение о том, что тесты завершены.

В строках 19-25 реализуется еще одна функция-член TBench – Report(). В строке 21 переменой result присваивается результат наследованной функции-члена Time() в строках 22-23 выводится сообщение о том, что затраченное время слишком мало для того, чтобы его можно было верно ценить. (если у вас возникло подобное сообщение, рекомендуется увеличить число тестов.) В строке 24 отображаются результаты измерений быстродействия в секундах.

Для того чтобы использовать класс TBench, следует создать объект и передать функции-члену Benchmark() число необходимых для выполнения тестов и адрес тестируемой функции. Затем следует вызвать функцию-член Report() . В листинге 3.3 демонстрируется эта последовательность действий, и он может послужить оболочкой для необходимых вам измерений производительности. После компиляции модулей TBENCH.CPP и BENCH.CPP требуется скомпоновать их с библиотечным файлом TCLASDBS.LIB, содержащим скомпилированный код класса TTimer. Если вы пользуетесь автономным компилятором, добавьте следующие две строки в файл TURBOC.CFG, находящийся в текущем каталоге:

3B-IC:\c 45\in Iude

-LC:\c 45\lic

Затем из командной строки DOS введите следующую команду для компиляции модуля BENCH.CPP и тестовой программы TBENCH.CPP, использующей класс TBench:

c tcen h cen h cidss.lic

В дополнение к заданию имен файлов модулей TBENCH и BENCH предыдущая команда передаст компоновщику имя библиотечного файла BC45 – BIDSS.LIB, в котором содержится скомпилированный код класса TTimer. Второй символ S в BIDSS означает малую (small) модуль памяти, используемую в программах для DOS по умолчанию. (в главе 19приводится более подробное объяснение использования моделей памяти в программировании для DOS и WINDOWS). Как уже отмечалось, класс TTimer, из которого выводится TBENCH, обращается к аппаратным средствам способом, не применимым для WINDOWS. Вы должны скомпилировать эту программу в качестве приложения для DOS.

.

Листинг 3.3. TBENCH.CPP

(тестирование класса TBen h)

1: #include<iostream.h>

2: #include<stdio.h>

3: #include ”cen h.h”

4:

5: #define NUMESTS 20000

6:

7: void Testfn((void);

8:

9: main()

10: {

11: TBen h test;

12:

13: out << “Testing sprintf() fun tion\n”;

14: test.Ben hmark(NUMTESTS. Testfn);

15: test.Report();

16: return 0;

17: }

18:

19: void Testfn(void)

20: {

21: har cuffer[80];

22: doucle d = 3.14159;

23:

24: sprintf(cuffer, “%1f” , d)

25: }

В строке 11 объявляется объект класса TBENCH с именем test. Поскольку С++ вызывает конструктор объекта класса (который вызовет конструктор базового класса Timer), вы можете быть уверены, что объект test соответствующим образом проинициализирован и, следовательно, готов к употреблению. После вывода короткого сообщения программа вызывает функцию-член Benchmark() (строка 14) и передает число необходимых для выполнения тестов, а также адрес тестируемой функции. В строке 15 вызывается функция-член Report() объекта test для вывода результатов тестов. Тестируемая функция (строки 19-25) исключительно для демонстрации вызывать функцию sprintf(). Для проведения другого испытания быстродействия заменить содержимое функции testfn() какими-нибудь другими операторами. Выполнение программы приводит к выводу следующего отсчета:

Testing sprintf() function

Running 20000 tests…

Tests completed

Elapsed time = = 4.118690 sec.