Форум: "Система";
Текущий архив: 2004.05.30;
Скачать: [xml.tar.bz2];
ВнизИзмерение времени с точностью до мс Найти похожие ветки
← →
Andrew_Rostov (2004-04-24 15:11) [0]Задача измерить время отработки процедуры. Наиболее точный результат получился с помошью:
var
TimeStart,TimeEnd:TDateTime;
TimeElapsed:TTimeStamp;
procedure OnClick;
begin
TimeStart:=Time;
ProcedureA;
TimeEnd:=Time;
TimeElapsed:=DateTimeToTimeStamp(TimeEnd-TimeStart); //время в мс
end;
При построении диаграммы времени выполнения получил ступеньки с высотой около 16 мс. Возможная причина - насколько я помню, системный таймер срабатывает каждые 16 мс.
Возможно ли в принцине измерять отрезки времени длиной меньше 16 мс?
← →
Kerk © (2004-04-24 15:16) [1]Измерять можно с точностью до 20мс.
← →
Anatoly Podgoretsky © (2004-04-24 15:27) [2]Измерить можно, стабильность получить нельзя
← →
panov © (2004-04-24 16:36) [3]Используй GetTickCount.
← →
evvcom © (2004-04-24 16:51) [4]Во время выполнения ProcedureA могут и скорее всего будут выполняться и другие процедуры других потоков, других процессов. Так что точного чистого времени выполнения процедуры в виндах получить не получится.
← →
N170 (2004-04-24 16:56) [5]Ещё как вариант - QueryPerformanceCounter() + QueryPerformanceFrequency(). Там и точность и стабильность.
(Забыли?!)
← →
Andrew_Rostov (2004-04-24 17:19) [6]Спасибо, а можно по подробнее о QueryPerformanceCounter() + QueryPerformanceFrequency() или GetTickCount?
Задача даже не в том, чтобы точно посчитать время отработки, а чтобы избавиться от "квантования" результатов на 16 мс отрезки времени - на графике зависимости времени работы от объема данных слишком явно видны ступеньки.
← →
vengo (2004-04-25 13:09) [7]Unit HighTimer;
interface
Uses Windows;
Type
THRTimer = Class(TObject)
Constructor Create;
Function StartTimer : Boolean;
Function ReadTimer : Double;
private
StartTime : Double;
ClockRate : Double;
public
Exists : Boolean;
End;
implementation
Constructor THRTimer.Create;
Var
QW : TLargeInteger;
BEGIN
Inherited Create;
Exists := QueryPerformanceFrequency(QW);
ClockRate := LARGE_INTEGER(QW).QuadPart;
END;
Function THRTimer.StartTimer : Boolean;
Var
QW : TLargeInteger;
BEGIN
Result := QueryPerformanceCounter(QW);
StartTime := LARGE_INTEGER(QW).QuadPart;
END;
Function THRTimer.ReadTimer : Double;
Var
ET : TLargeInteger;
BEGIN
QueryPerformanceCounter(ET);
Result := 1000000*( LARGE_INTEGER(ET).QuadPart - StartTime)/ClockRate;
END;
end.
← →
Andrew_Rostov (2004-04-25 16:29) [8]Насколько я понимаю для использования нужно:
1) поместить этот код в файл и прописать в uses имя этого файла
2) объявить глобальную переменную My_Timer:THRTimer;
3) при создании формы вызвать My_Timer.Create;
4) для измерения времени делать следующее:
My_Timer.StartTimer;
ProcedureA;
TimeElapsed:=My_Timer.ReadTimer;
5) при закрытии формы вызвать My_Timer.Free
Проблема в том, что при создании таймера получаем исключение на строке Exists := QueryPerformanceFrequency(QW);
Если же My_Timer.Create не вызывать, то при чтении значения таймера ClockRate будет равным 0 и получаем исключение деления на 0.
← →
panov © (2004-04-25 16:51) [9]function TickCount:Int64;
begin
QueryPerformanceCounter(Result);
end;
function DeltaTickToSeconds(const Delta: Int64):Double;
var
TickFreq: Int64;
begin
QueryPerformanceFrequency(TickFreq);
Result := Delta/TickFreq;
end;
var
DeltaCounter: int64;
begin
DeltaCounter := TickCount;
MyProc; //измеряемая процедура
DeltaCounter := TickCount-DeltaCounter
ShowMessage(FloatToStr(DeltaCounter)+" secouds");
Страницы: 1 вся ветка
Форум: "Система";
Текущий архив: 2004.05.30;
Скачать: [xml.tar.bz2];
Память: 0.46 MB
Время: 0.036 c