TURBO PASCAL |
Новости
|
5.3.3. Тестовая программаВ следующей программе демонстрируются основные приемы работы с объектами и подпрограммами модуля F_EMS. Работа программы заключается в выполнении нескольких тестов. Вначале с помощью функции IsEMS определяется доступность EMS— памяти: если функция возвращает False, выводится сообщение Нет ЕМЗ-памяти. или не установлен EMM и программа завершает работу. Если память доступна, сообщается общий объем памяти в страницах и количество свободных EMS— страниц. Второй тест заключается в сопоставлении скорости доступа к стандартной и EMS— памяти. Для этого в куче создается несколько массивов длинных целых чисел по 16 Кбайт каждый, которые заполняются последовательно возрастающими значениями, после чего подсчитывается сумма всех элементов всех массивов. На экран выводится контрольная сумма и время, затраченное на работу. Затем создается объект TEMSVector такой же длины, как суммарная длина всех массивов в куче, его элементы заполняются монотонно возрастающими значениями, после чего подсчитывается контрольная сумма массива. Эта сумма и время счета также выводятся на экран. Разбивка на массивы по 16 Кбайт сделана, с одной стороны, чтобы приблизительно уравнять условия теста, а с другой, — это неизбежное следствие известного ограничения Турбо Паскаля: за одно обращение к менеджеру кучи нельзя зарезервировать больше 65521 байта. Этот тест показывает, что доступ к элементам EMS— массива идет в 5...10 раз медленнее, чем к массивам в стандартной памяти. Следующий тест сохраняет созданный объект TEMSVector на диске, затем уничтожает объект и создает его вновь с помощью конструктора Load, после чего еще раз подсчитывает и выводит контрольную сумму массива. В ходе выполнения четвертого теста создается объект TEMSText и в него считывается исходный текст тестовой программы. Затем средствами модуля F_Text на экране создается окно, в которое выводится эталонный текст программы, считанный непосредственно из PAS—файла, и текст, полученный из объекта. Если объект функционирует нормально, обе колонки окна должны содержать идентичные строки, В следующем тесте проверяется работа объекта TEMSScreen сначала для текстового, а затем графического режима работы экрана. При инициации графического режима предполагается, что нужный BGI— драйвер располагается в текущем каталоге. Если это не так, следует скорректировать вызов процедуры InitGraph, указав путь к каталогу с этим драйвером. { +--_--_----_------_------------------+ I Демонстрация основных возможностей ¦ ¦ модуля F_EMS I +------------------------------------+ ; Uses CRT,Graph,F_EMS,F_Text; type TV = array [O.-MaxInt div 2-1] of Longint; var All,Pages: Word; k,j,x: Longint; Vec: TEMSVector; Тех: TEMSText; Scr: TEMSScreen; t: Longint; d,r,e: Integer; PV: array [0..40] of ^V; Sz: Longint; Sum: Comp; f: file; ft: Text; s,ss: String; const LPage=16*1024; label L1,L2; Function HexW(X: Word): String; {Возвращает 16-ричное написание X} const HS: array [0..15] of Char = '0123456789ABCDEF'; var S: String; k: Byte; begin C; .= II. 0 . — / for k := 3 downto 0 do S := S+HS[(X shr (k*4)) and 15]; HexW := S end; {UexW} ^———\————————^ Procedure GetTime; {Помещает в t системное время, выравненное на границу 55-мс интервала} begin t := MemL[0:$46C] ; while t=MemL[0:$46C] do; end; {Get Time} _'————————.——; begin {Основная программа} {Проверяем наличие EMM} If not IsEMS then begin WriteLn('Нет ЕМЗ-памяти или не установлен EMM'); Halt end; Colors(LightGray,Black); CIrScr; {Сообщаем номер версии, общую и доступную память} WriteLn('Используется EMM версии ',GetEMMVersion); WriteLn(' Сегмент окна отображения $',HexW(EMSSeg)); GetEMSInfo(All,Pages) ; WriteLn(' Всего страниц : ',А11,' (', round(All*16.0*1024),' байт)'); Sz := round(Pages*16.0*1024); WriteLn (' Свободно страниц: ',Pages,' (',Sz,' байт)'); {Определяем количество X 16-Кбайтных страниц в куче} х := MaxAvail div LPage; if x>Pages then x := Pages; {Уравниваем с EMM} {Распределяем в куче массивы из 4096 длинных целых чисел} dec (х) ; for k := 0 to x do if MaxAvail>=LPage then GetMem(PV[k],LPage) ; x := k; Sz :==succ (x) *LPage div 4; WriteLn('Создаем массив из ',Sz, ' длинных целых чисел в куче...'); GetTime; {Засекаем время} for j := 0 to x do for k := 0 to LPage div 4-1 do begin PVEjJ'^k] := j* (LPage div 4)+k; if PVtjI'^k] mod 1000=0 then begin Write (PVCjI^k:] :10); GotoXY(l,WhereY) end end; {Подсчитываем его сумму} WriteLn('Подсчитываем его сумму...'); Sum := 0; for j := 0 to x do for k := 0 to LPage div 4-1 do begin Sum := Sum+PV[j] •"[k] ; if PV[j]л[k] mod 1000=0 then begin Write (PVCjI^k] :10) ; GotoXY(l,WhereY) end end; WriteLn('Сумма элементов = ':30,Sum:11:0,',время счета = (MemL[O:$46C]-t)*55/1000:5:2,' секунд') ; {Освобождаем кучу} for k : = 0 to x do FreeMem(PV[k],LPage) ; {Создаем массив в EMS} WriteLn('Тот же массив в EMS-памяти...') ; Vec.Init(4,0,Sz-1); {4-длина элемента;..Sz-1 - индексы} if not EMSErrorFlag then with Vec do begin (Если создан успешно} GetTime; {Засекаем время} for k := 0 to Sz-1 do begin Setltem(k,k); {Помещаем очередной эл-т} if k mod 1000=0 then begin {Сообщаем о каждом 1000-м} Write(k:10) ; GotoXY(l,WhereY) end end; {Вычисляем сумму элементов} WriteLn('Суммируем элементы...'); Sum : = 0 ; for k := 0 to Sz-1 do begin Sum := Sum+LongIntItemfk); if k mod 1000=0 then begin {Сообщаем о каждом 1000-м} Write(k:10) ; GotoXY(l,WhereY) end end end else Halt; WriteLn('Сумма элементов = ':30,Sum:11:0,', время счета = Доступ к отображаемой памяти 155 (MemL[O:$46C]-t)*55/1000:5:2,' секунд') ; WriteLn('Сохраняем массив в файле TESTEMS.$$$...'); Assign(f,'testems.$$$'); {$!-} Rewrite(f,l) ; {$!+} if IQResultoO then begin WriteLn('Ошибка при создании файла!'); Vec.Done; Goto LI end; Vec.Store(f); {Сохраняем массив} if EMSErrorFlag then begin {Была ошибка при сохранении} Vec.Done; Goto LI end; Vec.Done; (Освобождаем EMS} {Читаем массив из файла} WriteLn('Читаем массив из файла...'); Seek(f,0); {Начало файла} Vec.Load(f); {Загружаем массив} Close (f) ; if EMSErrorFlag then Goto LI; {Была ошибка} WriteLn('Еще раз подсчитываем его сумму...'); Sum : = 0 ; for k := 0 to Sz-1 do begin Sum := Vec.LongIntItem(k)+Sum; if k mod 500=0 then begin Write(k:10) ; GotoXY(l,WhereY) end end; WriteLn('Сумма = ':30,Sum:11:0); Vec.Done; LI: {Определяем длину файла с текстом программы} s := copytParamStrtO^l/PosC.'/ParamStrtO^+'pas'; Assign (f,s); Reset(f,l) ; {Определяем количество SZ требуемых ему страница ST. := (FileSize(f)+LPage-l) div LPage; Closed) ; Assign(ft,s) ; Reset(ft) ; {Создаем объект TEMSText} WriteLn('Создаем объект TEMSText'); Тех.Init(Sz*Lpage) ; if EMSErrorFlag then Halt; {Читаем файл и записываем его в TEMSText} WriteLn('Помещаем в него файл '+S); while not (EOF(ft) or EMSErrorFlag) do begin ReadLn(ft,s); (Читаем строку} Тех.Setltem(s) {Помещаем ее в EMS} end; if EMSErrorFlag then Goto L2; {Проверяем записанное} Reset(ft); {Начало файла} Tex.Pos := 0; {Начало текста в EMS} for k := 1 to 16 do WriteLn; {Готовим место для окон} Colors(Yellow/Blue); {Цвет вывода} SetWindowd, 10, 80,23,1, 1 Исходный файл: '+ #196#196#196#196#196#196#196#196#196#196#196#196#196+ #196#196#196' Текст в EMS: ',True,False,False); while not EOF(ft) do begin ReadLn(ft,s); ss := Tex.GetItem; if Length(s)>38 then s[0] := #38; While Length(s)<39 do s := s+' '; s := s+ss; if Length(s)>77 then s[0] := #77; WriteLn(s) end; Тех.Done; Colors(LightGray,Black); Window(1,1,80,25) ; GotoXY(l,25) ; L2: {Проверка объекта TEMSScreen} Write('Сохраняем копию текстового экрана. '); Scr.Init; if not EMSErrorFlag then Scr.PutScreen; {Сохраняем копию в EMS} if EMSErrorFlag then Halt; {Была ошибка} x := WhereX; {Запоминаем положение курсора} WriteLn('Нажмите любую клавишу...') ; if ReadKey=#O then k := ord(ReadKey); {Создаем окно в центре экрана и заполняем его случайным цветом} CIrScr; SetWindow(10,7,70,18,2,' Нажмите любую клавишу...', False/True,False); while not KeyPressed do begin GotoXY(Random(59)+2,Random(10)+2) ; TextBackground(Random(8)); Write (' ') end; if ReadKey=#0 then k :== ord(ReadKey); Scr.GetScreen; {Восстанавливаем экран} Window(l,l,80,25) ; TextBackground(Black) ; GotoXY(x,25) ; Scr.Done; {Проверяем графический режим} WriteLn(#13#10'Для перехода в графический '+ "режим нажмите любую клавишу...'); if ReadKey=#0 then k := ord(ReadKey) ; d := detect; InitGraph(d,r,'') ; e := GraphResult; if e о 0 then begin {Ошибка инициации графики} WriteLn(GraphErrorMsg(e)) ; Halt end; {Инициируем Scr заново - новый режим экрана!} Scr.Init; Line(0,0,GetMaxX,GetMaxY); {Диагональные линии} Line(O,GetMaxY,GetMaxX,O) ; Scr.PutScreen; {Сохраняем изображение}. while not (KeyPressed or EMSErrorFlag) do begin ClearDevice; {Очищаем экран} Scr.GetScreen; {Восстанавливаем изображение} end; Scr.Done; CloseGraph; end. |
(с)Все права защищены По всем интересующим вопросам прошу писать на электронный адрес |