IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Delphi Discussion :

[XE] Calculer le temps de traitement d'une fonction


Sujet :

Langage Delphi

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Modérateur
    Avatar de Rayek
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2005
    Messages
    5 236
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 236
    Par défaut [XE] Calculer le temps de traitement d'une fonction
    Bonjour,

    En prenant exemple sur le code de Paul Toth, je me suis dis qu'il serait pas mal de faire un code dans ce style en passant des fonctions en paramètres d'une autres afin qu'elle me retourne le temps mis pas celle ci.

    Ci-dessous un début d'idée sur le fonctionnement que je voudrais réaliser.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
     
    TProcess : function : integer of Object;
     
    TMainClass = Class(TObject)
      public
        // Diverses fonction du style function (Nombre de param variable) : Integer;
     
        function CalcTime(AProcessName : String;AProcess : TProcess; Logs : TStringList) : Integer;
    end;
     
    function TMainClass.CalcTime(AProcessName : String;AProcess : TProcess; Logs : TStringList) : Integer
    var
    var
      Begintime, endtime,TickPerSec : int64;
      iTmp : Int64;
     
    begin
      QueryPerformanceCounter(BeginTime);
     
      Result := Process;
     
      QueryPerformanceCounter(EndTime);
      QueryPerformanceFrequency(TickPerSec);
      iTmp := Round((EndTime - BeginTime) / TickPerSec * 1000);
      Logs.Add(Format(AProcessName + ' %d',[iTmp]));
    end;
    Je pense que cela ne sera pas fonctionnel en l'état au vu que les fonctions n'ont pas un même nombre de paramètres.

    Mes questions :

    - Est ce réalisable ?
    - Si oui, que manque-t-il à ce code ? Doit on écrire d'une autre manière ?

    Merci
    Modérateur Delphi

    Le guide du bon forumeur :
    __________
    Rayek World : Youtube Facebook

  2. #2
    Expert éminent
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Par défaut
    ça me parait bien, mais je connais un outils très pratique pour cela c'est SamplingProfiler.

    ce programme laisse l'application tourner et vient régulièrement regarder ce qu'elle est en train de faire. Dès lors elle établi un rapport sur le temps passé dans chaque portion de code. Je trouve cela très instructif.
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  3. #3
    Modérateur
    Avatar de Rayek
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2005
    Messages
    5 236
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 236
    Par défaut
    Citation Envoyé par Paul TOTH Voir le message
    ça me parait bien, mais je connais un outils très pratique pour cela c'est SamplingProfiler.

    ce programme laisse l'application tourner et vient régulièrement regarder ce qu'elle est en train de faire. Dès lors elle établi un rapport sur le temps passé dans chaque portion de code. Je trouve cela très instructif.
    Cela a l'air d'être pas mal comme outils mais j'ai besoin des informations dans mes Logs.

    donc après test, cela ne fonctionne pas

    Code Définition de la classe : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    TCommandeClass = Class(TMainClass)
       private
         function SetData(ART_ID, SSF_ID : Integer) : Integer;
       public
        function DoMajTable(ADoMaj : Boolean) : Boolean;override;
    end;

    Code Procedure d'exécution de la classe : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    function TCommandeClass.DoMajTable(ADoMaj : Boolean) : Boolean;
    begin
      // Si je met
      CalcTime('SetData',SetData(ART_ID, SSF_ID : Integer),FerrLogs);
      // J'ai l'erreur type incompatible TProcess et Integer
     
      // Si je test
      CalcTime('SetData',TProcess(SetData(ART_ID, SSF_ID : Integer)),FerrLogs);
     // J'ai une violation d'accès.
     
    end;


    Citation Envoyé par ShaiLeTroll Voir le message
    Surtout que tu risques de compter le temps de ta gestion du re-passage de paramètre (genre par pointeur sur la pile ou les trucs de SJRD dans SEPI)

    Perso, je me suis fait 3 fonctions que j’utilise si j'ai ce besoin

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    procedure GetBeginTime(var Value: Int64);
    begin
       QueryPerformanceCounter(Value);
    end;
     
    function ElapsedTime(var BeginTime: Int64): Cardinal;
    var
       EndTime, TickPerSec: Int64;
    begin
       QueryPerformanceCounter(EndTime);
       QueryPerformanceFrequency(TickPerSec);
       Result := Round((EndTime - BeginTime) / TickPerSec * 1000);
    end;
     
    function FormatMS(MilliSecondes: Cardinal): string;
    var
      Hour, Min, Sec: Cardinal;
    begin
      Hour := MilliSecondes div 3600000;
      MilliSecondes := MilliSecondes mod 3600000;
      Min := MilliSecondes div 60000;
      MilliSecondes := MilliSecondes mod 60000;
      Sec := MilliSecondes div 1000;
      MilliSecondes := MilliSecondes mod 1000;
      Result := Format('%.2d:%.2d:%.2d:%.3d', [Hour, Min, Sec, MilliSecondes]);
    end;
    J'utilise déjà quelques choses dans le style mais j'ai plus de 50 fonctions à encadrer et cela serait plus simple de passer par une procèdure/fonction où j'ai juste à passer en paramètre celle que je veux tester.
    Modérateur Delphi

    Le guide du bon forumeur :
    __________
    Rayek World : Youtube Facebook

  4. #4
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 115
    Par défaut
    J'utilise déjà quelques choses dans le style mais j'ai plus de 50 fonctions à encadrer et cela serait plus simple de passer par une procèdure/fonction où j'ai juste à passer en paramètre celle que je veux tester.
    Le chronometrage, tu veux le conserver par la suite ?
    Effectivement, je ne fais cela que lorsque je constate une lenteur, c'est un code jetable le temps d'optimiser !
    Je n'ai jamais conserver une mesure de temps dans une application réelle !


    Le Passage de paramètre d'une fonction c'est complexe
    En plus là, tu ne passes plus le pointeur sur la fonction mais le résultat de son appel dans les codes ci-dessus

    Lit l'article de de SJRD sur les conventions d'appels et comment les bidouiller

    Un autre idée, au lieu de passer la méthode directement, il faut passer une classe abstraite ou interface un peu comme le TThread

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    TProcess = Class(TObject)
    public
      procedure Execute(); virtual; abstract;
      procedure CalcTime(AProcessName : String; Logs : TStringList);
    end;
    dans le code de CalcTime
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    // ChronoStart
    Self.Execute();
    // ChornoEnd
    un exemple

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    TMonProcess = Class(TMonProcess )
    private
      FParam1: Integer; 
      FParam2: string;
      FResult: Integer;
    public
      constructor(AParam1: Integer; AParam2: string);
      procedure Execute(); override;
    end;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    with TMonProcess.Create(1, 'Deux') do
    try
      CalcTime('...', Logs);
    finally
      Free();
    end;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    procedure TMonProcess.Execute(); 
    begin
      FResult := Length(Param2) - Param1);
    end;
    et pour simplifier l'appel, une méthode statique

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    TMonProcess = Class(TMonProcess )
    ...
      class function Call(AParam1: Integer; AParam2: string; AProcessName : String; Logs : TStringList): Integer;
    end;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    class function Call(AParam1: Integer; AParam2: string; AProcessName : String; Logs : TStringList): Integer;
    begin
      with Self.Create(AParam1, AParam2) do
      try
        CalcTime(AProcessName, Logs);
        Result := FResult;
      finally
        Free();
      end;
    end;
    l'appel
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    TMonProcess.Call(1, 'Deux', '...', Logs);
    EDIT avec ton exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    TSetData = Class(TMonProcess)
    private
      FART_ID : Integer;
      FSSF_ID : Integer;
      FResult: Integer;
    public 
      constructor Create(ART_ID, SSF_ID : Integer);
      procedure Execute(); override;
     
      class function SetData(ART_ID, SSF_ID : Integer) : Integer;
    end;
     
    constructor TSetData.Create(ART_ID, SSF_ID : Integer);
    begin
      FART_ID := ART_ID;
      FSSF_ID := SSF_ID;
    end;
     
    procedure TSetData.Execute(); override;
    begin
      Result := FART_ID * FSSF_ID;
    end;
     
    class function TSetData.SetData(ART_ID, SSF_ID : Integer; AProcessName : String; Logs : TStringList): Integer;
    begin
      with Self.Create(ART_ID, SSF_ID) do
      try
        CalcTime(AProcessName, Logs);
        Result := FResult;
      finally
        Free();
      end;
    end;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    procedure TCommandeClass.DoMajTable(ADoMaj : Boolean) : Boolean;
    begin
      Result := TSetData.SetData(ART_ID, SSF_ID, 'SetData', FerrLogs);
    end;
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  5. #5
    Modérateur
    Avatar de Rayek
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2005
    Messages
    5 236
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 236
    Par défaut
    Trop de boulot pour mettre en place cette solution.

    Je comptais garder le chronométrage mais je pense que je vais le faire à la mimine et je les mettrais en commentaires
    Modérateur Delphi

    Le guide du bon forumeur :
    __________
    Rayek World : Youtube Facebook

  6. #6
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 115
    Par défaut
    Pense au directive de compilation pour encadrer la mesure de temps et pouvoir ainsi l'activer pour des versions de test

    En C++Builder, avec les macro, on peut facilement ajouter du code selon les directives de compilations, typique pour ce genre de manip, il me semblait que DelphiXE2 apportait des nouveautés sur le pré-compilateur
    C'est idéal pour ce genre de code "jetable"

    Peut-etre qu'avec les méthodes anonymes et les génériques, tu pourrais simplifer ma proposition, je n'ai encore jamais pratiqué cela en Delphi.
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  7. #7
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 115
    Par défaut
    Surtout que tu risques de compter le temps de ta gestion du re-passage de paramètre (genre par pointeur sur la pile ou les trucs de SJRD dans SEPI)

    Perso, je me suis fait 3 fonctions que j’utilise si j'ai ce besoin d'optimisation

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    procedure GetBeginTime(var Value: Int64);
    begin
       QueryPerformanceCounter(Value);
    end;
     
    function ElapsedTime(var BeginTime: Int64): Cardinal;
    var
       EndTime, TickPerSec: Int64;
    begin
       QueryPerformanceCounter(EndTime);
       QueryPerformanceFrequency(TickPerSec);
       Result := Round((EndTime - BeginTime) / TickPerSec * 1000);
    end;
     
    function FormatMS(MilliSecondes: Cardinal): string;
    var
      Hour, Min, Sec: Cardinal;
    begin
      Hour := MilliSecondes div 3600000;
      MilliSecondes := MilliSecondes mod 3600000;
      Min := MilliSecondes div 60000;
      MilliSecondes := MilliSecondes mod 60000;
      Sec := MilliSecondes div 1000;
      MilliSecondes := MilliSecondes mod 1000;
      Result := Format('%.2d:%.2d:%.2d:%.3d', [Hour, Min, Sec, MilliSecondes]);
    end;
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

Discussions similaires

  1. calculer le temps d'exécution d'une fonction
    Par info_sara dans le forum C++/CLI
    Réponses: 4
    Dernier message: 08/06/2015, 16h02
  2. calculer le temps d'éxécution d'une fonction
    Par phpines dans le forum Général Python
    Réponses: 3
    Dernier message: 09/04/2013, 09h47
  3. Comment calculer le temps d'exécution d'une fonction
    Par gege2061 dans le forum Télécharger
    Réponses: 0
    Dernier message: 30/11/2010, 16h19
  4. Calculer le temps d'exécution d'une fonction
    Par ZAYDOUN dans le forum MATLAB
    Réponses: 3
    Dernier message: 11/07/2008, 14h45
  5. Réponses: 3
    Dernier message: 11/03/2006, 15h35

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo