Intéressant

Mesurer avec précision le temps écoulé à l'aide du compteur de performances Delphi

Mesurer avec précision le temps écoulé à l'aide du compteur de performances Delphi

Pour les applications de base de données de bureau courantes, l'ajout d'une seconde au temps d'exécution d'une tâche fait rarement la différence pour les utilisateurs finaux. Toutefois, lorsque vous devez traiter des millions de feuilles d'arbre ou générer des milliards de nombres aléatoires uniques, la vitesse d'exécution devient plus importante.

Expiration de votre code

Dans certaines applications, il est important de disposer de méthodes de mesure du temps extrêmement précises et très précises. Heureusement, Delphi fournit un compteur hautes performances pour qualifier ces temps.

Utiliser RTL À présentUne fonction

Une option utilise la fonction Maintenant. À présent, défini dans le SysUtils unité, renvoie la date et l'heure actuelles du système.

Quelques lignes de code mesurent le temps écoulé entre le début et la fin d'un processus:

var

démarrer, arrêter, écoulé: TDateTime;

commencer

commencer: = maintenant;

// TimeOutThis ();

stop: = Now;

écoulé: = stop - start;

fin;

La fonction Maintenant renvoie la date et l'heure actuelles du système, avec une précision pouvant aller jusqu'à 10 millisecondes (Windows NT et versions ultérieures) ou 55 millisecondes (Windows 98).

Pour de très petits intervalles, la précision de "Maintenant" n'est parfois pas suffisante.

Utilisation de l'API Windows GetTickCount

Pour des données encore plus précises, utilisez le GetTickCount Fonction API Windows. GetTickCount récupère le nombre de millisecondes écoulées depuis le démarrage du système, mais la fonction n'a qu'une précision de 1 ms et peut ne pas toujours être exacte si l'ordinateur reste allumé pendant de longues périodes.

Le temps écoulé est stocké sous forme de valeur DWORD (32 bits). Par conséquent, le temps sera à zéro si Windows est exécuté en continu pendant 49,7 jours.

var

démarrer, arrêter, écoulé: cardinal;

commencer

start: = GetTickCount;

// TimeOutThis ();

stop: = GetTickCount;

écoulé: = stop - start; // millisecondesend;

GetTickCount est également limité à la précision du temporisateur système (10/55 ms).

High Precision Timing Out Votre code

Si votre PC prend en charge un compteur de performance haute résolution, utilisez la QueryPerformanceFrequency Fonction API Windows pour exprimer la fréquence, en comptes par seconde. La valeur du nombre dépend du processeur.

le QueryPerformanceCounter function récupère la valeur actuelle du compteur de performance haute résolution. En appelant cette fonction au début et à la fin d'une section de code, une application utilise le compteur en tant que minuteur haute résolution.

La précision des minuteries haute résolution est d'environ quelques centaines de nanosecondes. Une nanoseconde est une unité de temps représentant 0,000000001 seconde, soit un milliardième de seconde.

TStopWatch: Implémentation Delphi d'un compteur haute résolution

Avec un clin d'œil aux conventions de nommage .Net, un compteur comme TStopWatch offre une solution Delphi haute résolution pour des mesures de temps précises.

TStopWatch mesure le temps écoulé en comptant les ticks de minuterie dans le mécanisme de minuterie sous-jacent.

  • le IsHighResolution Cette propriété indique si le minuteur est basé sur un compteur de performance haute résolution.
  • le Début La méthode commence à mesurer le temps écoulé.
  • le Arrêtez La méthode arrête de mesurer le temps écoulé.
  • le Millésecondes écoulées propriété obtient le temps total écoulé en millisecondes.
  • le Écoulé propriété obtient le temps total écoulé en ticks du minuteur.

unité Chronomètre;

interface

les usages Windows, SysUtils, DateUtils;

type TStopWatch = classe

  privé

fFrequency: TLargeInteger;

fIsRunning: booléen;

résolution haute: booléen;

fStartCount, fStopCount: TLargeInteger;

    procédure SetTickStamp (var lInt: TLargeInteger);
    

une fonction GetElapsedTicks: TLargeInteger;
    

une fonction GetElapsedMilliseconds: TLargeInteger;
    

une fonction GetElapsed: string;
  

Publique

    constructeur Créer(const startOnCreate: boolean = false);
    

procédure Début;
    

procédure Arrêtez;
    

propriété IsHighResolution: boolean lis fIsHighResolution;
    

propriété ElapsedTicks: TLargeInteger lis GetElapsedTicks;
    

propriété ElapsedMilliseconds: TLargeInteger lis GetElapsedMilliseconds;
    

propriété Écoulé: chaîne lis GetElapsed;
    

propriété IsRunning: booléen lis fIsRunning;
  

fin;

la mise en oeuvre

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

commencer

hérité Créer;

fIsRunning: = false;

fIsHighResolution: = QueryPerformanceFrequency (fFrequency);

  si non résolution haute puis fFrequency: = MSecsPerSec;
  

si startOnCreate puis Début;

fin;

une fonction TStopWatch.GetElapsedTicks: TLargeInteger;

commencer

résultat: = fStopCount - fStartCount;

fin;

procédure TStopWatch.SetTickStamp (var lInt: TLargeInteger);

commencer

  si résolution haute puis

QueryPerformanceCounter (lInt)

autre

lInt: = MilliSecondOf (Now);

fin;

une fonction TStopWatch.GetElapsed: chaîne;

var

dt: TDateTime;

commencer

dt: = ElapsedMilliseconds / MSecsPerSec / SecsPerDay;

result: = Format ('% d jours,% s', tronc (dt), FormatDateTime ('hh: nn: ss.z', Frac (dt)));

fin;

une fonction TStopWatch.GetElapsedMilliseconds: TLargeInteger;

commencer

résultat: = (MSecsPerSec * (fStopCount - fStartCount)) div fFrequency;

fin;

procédure TStopWatch.Start;

commencer

SetTickStamp (fStartCount);

fIsRunning: = true;

fin;

procédure TStopWatch.Stop;

commencer

SetTickStamp (fStopCount);

fIsRunning: = false;

fin;

fin.

Voici un exemple d'utilisation:

var

sw: TStopWatch;

écouléMillisecondes: cardinal;

commencer

sw: = TStopWatch.Create ();

  essayer

sw.Start;

    // TimeOutThisFunction ()

sw.Stop;

elapsedMilliseconds: = sw.ElapsedMilliseconds;

  enfin

sw.free;

  fin;

fin;