Interesante

Mida con precisión el tiempo transcurrido utilizando el contador de rendimiento de Delphi

Mida con precisión el tiempo transcurrido utilizando el contador de rendimiento de Delphi



We are searching data for your request:

Forums and discussions:
Manuals and reference books:
Data from registers:
Wait the end of the search in all databases.
Upon completion, a link will appear to access the found materials.

Para las aplicaciones de base de datos de escritorio de rutina, agregar un solo segundo al tiempo de ejecución de una tarea rara vez hace una diferencia para los usuarios finales, pero cuando necesita procesar millones de hojas de árbol o generar miles de millones de números aleatorios únicos, la velocidad de ejecución se vuelve más importante.

Tiempo de espera de su código

En algunas aplicaciones, los métodos de medición de tiempo muy precisos y de alta precisión son importantes y, afortunadamente, Delphi proporciona un contador de alto rendimiento para calificar estos tiempos.

Usando RTL's AhoraFunción

Una opción usa la función Ahora. Ahora, definido en el SysUtils unidad, devuelve la fecha y hora actuales del sistema.

Algunas líneas de código miden el tiempo transcurrido entre el "inicio" y la "detención" de algún proceso:

var

inicio, parada, transcurrido: TDateTime;

empezar

inicio: = ahora;

// TimeOutThis ();

parada: = ahora;

transcurrido: = detener - iniciar;

fin;

La función Ahora devuelve la fecha y hora actuales del sistema con una precisión de hasta 10 milisegundos (Windows NT y posterior) o 55 milisegundos (Windows 98).

Para intervalos muy pequeños, la precisión de "Ahora" a veces no es suficiente.

Uso de la API de Windows GetTickCount

Para obtener datos aún más precisos, use el GetTickCount Función API de Windows. GetTickCount recupera la cantidad de milisegundos que han transcurrido desde que se inició el sistema, pero la función solo tiene la precisión de 1 ms y puede que no siempre sea precisa si la computadora permanece encendida durante largos períodos de tiempo.

El tiempo transcurrido se almacena como un valor DWORD (32 bits). Por lo tanto, el tiempo se ajustará a cero si Windows se ejecuta de forma continua durante 49,7 días.

var

inicio, parada, transcurrido: cardenal;

empezar

inicio: = GetTickCount;

// TimeOutThis ();

detener: = GetTickCount;

transcurrido: = detener - iniciar; // milisegundos;

GetTickCount También se limita a la precisión del temporizador del sistema (10/55 ms).

Alta precisión caduca su código

Si su PC admite un contador de rendimiento de alta resolución, use el QueryPerformanceFrequency Función API de Windows para expresar la frecuencia, en conteos por segundo. El valor del recuento depende del procesador.

los QueryPerformanceCounter La función recupera el valor actual del contador de rendimiento de alta resolución. Al llamar a esta función al principio y al final de una sección de código, una aplicación usa el contador como un temporizador de alta resolución.

La precisión de los temporizadores de alta resolución es de unos pocos cientos de nanosegundos. Un nanosegundo es una unidad de tiempo que representa 0.000000001 segundos, o 1 billonésima de segundo.

TStopWatch: implementación de Delphi de un contador de alta resolución

Con un guiño a las convenciones de nombres .Net, un contador como TStopWatch ofrece una solución de Delphi de alta resolución para mediciones de tiempo precisas.

TStopWatch mide el tiempo transcurrido contando los tics del temporizador en el mecanismo del temporizador subyacente.

  • los IsHighResolution La propiedad indica si el temporizador se basa en un contador de rendimiento de alta resolución.
  • los comienzo El método comienza a medir el tiempo transcurrido.
  • los Detener El método deja de medir el tiempo transcurrido.
  • los Milisegundos transcurridos La propiedad obtiene el tiempo total transcurrido en milisegundos.
  • los Transcurrido La propiedad obtiene el tiempo total transcurrido en tics de temporizador.

unidad Cronógrafo;

interfaz

usos Windows, SysUtils, DateUtils;

tipo TStopWatch = clase

  privado

f Frecuencia: TLargeInteger;

fIsRunning: boolean;

fIsHighResolution: boolean;

fStartCount, fStopCount: TLargeInteger;

    procedimiento SetTickStamp (var lInt: TLargeInteger);
    

función GetElapsedTicks: TLargeInteger;
    

función GetElapsedMilliseconds: TLargeInteger;
    

función GetElapsed: cadena;
  

público

    constructor Crear(const startOnCreate: boolean = false);
    

procedimiento Comienzo;
    

procedimiento Detener;
    

propiedad IsHighResolution: boolean leer fIsHighResolution;
    

propiedad ElapsedTicks: TLargeInteger leer GetElapsedTicks;
    

propiedad ElapsedMilliseconds: TLargeInteger leer GetElapsedMilliseconds;
    

propiedad Transcurrido: cadena leer GetElapsed;
    

propiedad IsRunning: boolean leer fIsRunning;
  

fin;

implementación

constructor TStopWatch.Create (const startOnCreate: boolean = false);

empezar

Crear heredado;

fIsRunning: = falso;

fIsHighResolution: = QueryPerformanceFrequency (fFrequency);

  si no fIsHighResolution luego f Frecuencia: = MSecsPerSec;
  

Si startOnCreate luego Comienzo;

fin;

función TStopWatch.GetElapsedTicks: TLargeInteger;

empezar

resultado: = fStopCount - fStartCount;

fin;

procedimiento TStopWatch.SetTickStamp (var lInt: TLargeInteger);

empezar

  Si fIsHighResolution luego

QueryPerformanceCounter (lInt)

más

lInt: = MilliSecondOf (ahora);

fin;

función TStopWatch.GetElapsed: cuerda;

var

dt: TDateTime;

empezar

dt: = ElapsedMilliseconds / MSecsPerSec / SecsPerDay;

resultado: = Formato ('% d días,% s', trunc (dt), FormatDateTime ('hh: nn: ss.z', Frac (dt)));

fin;

función TStopWatch.GetElapsedMilliseconds: TLargeInteger;

empezar

resultado: = (MSecsPerSec * (fStopCount - fStartCount)) div fFrequency;

fin;

procedimiento TStopWatch.Start;

empezar

SetTickStamp (fStartCount);

fIsRunning: = verdadero;

fin;

procedimiento TStopWatch.Stop;

empezar

SetTickStamp (fStopCount);

fIsRunning: = falso;

fin;

fin.

Aquí hay un ejemplo de uso:

var

sw: TStopWatch;

milisegundos transcurridos: cardinal;

empezar

sw: = TStopWatch.Create ();

  tratar

sw.Start;

    // TimeOutThisFunction ()

sw.Stop;

elapsedMilliseconds: = sw.ElapsedMilliseconds;

  finalmente

sw.Free;

  fin;

fin;