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

Composants VCL Delphi Discussion :

Optimisation de l'initialisation des composants


Sujet :

Composants VCL Delphi

  1. #1
    Membre régulier
    Femme Profil pro
    Inscrit en
    Avril 2007
    Messages
    209
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Suisse

    Informations forums :
    Inscription : Avril 2007
    Messages : 209
    Points : 93
    Points
    93
    Par défaut Optimisation de l'initialisation des composants
    Bonjour à tous,

    Afin d'uniformiser facilement mes composants et également pour pouvoir modifier rapidement l'apparence ou les propriétés de certains composants, j'appel à l'ouverture de chacunes de mes fiches une procédure d'initialisation:

    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
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
     
    Procedure ModifStyleFiche(MaForm_ : TForm);
     
    Var
       I : Integer;
       TempCmpn : TComponent;
     
    Begin
         Try
            If MaForm_ = Nil Then Exit;
     
            MaForm_.Font.Size:=8;
            MaForm_.Color:=clWhite;
     
            For I:=1 To MaForm_.ComponentCount Do
            Begin
     
                 If MaForm_.Components[I-1] is TAdvGlowButton Then       
                 Begin
                      TempCmpn:=MaForm_.Components[I-1];
                      TAdvGlowButton(TempCmpn).SetComponentStyle(tsOffice2013White);
                      TAdvGlowButton(TempCmpn).Appearance.BorderColor:=clBlack;
                      TAdvGlowButton(TempCmpn).Appearance.BorderColorChecked:=$00FAFAFA;
                      TAdvGlowButton(TempCmpn).Appearance.BorderColorDisabled:=clBlack;
                      TAdvGlowButton(TempCmpn).Appearance.BorderColorDown:=clActiveCaption;
    					//...
                 End;
     
                 If MaForm_.Components[I-1] is TAdvStringGrid Then
                 Begin
                      TempCmpn:=MaForm_.Components[I-1];
                      TAdvStringGrid(TempCmpn).Ctl3D:=False;
                      TAdvStringGrid(TempCmpn).FixedColor:=clWhite;
                      TAdvStringGrid(TempCmpn).FixedFont.Color:=clNavy;
                      TAdvStringGrid(TempCmpn).FixedFont.Style:=[];
                      TAdvStringGrid(TempCmpn).ControlLook.FixedGradientFrom:=clWhite;
                      TAdvStringGrid(TempCmpn).ControlLook.FixedGradientTo:=clWhite;
    				  //...
                 End;
    			 //...
            End;
         Except
         End;
    End;
    Le problème c'est que forcément, sur certaines de mes fiches qui peuvent être assez volumineuse, l'ouverture est ralentie par cette fonction (3-4 secondes dans certains cas). existe-t-il un moyen plus efficace de gérer ce genre de chose?

    Pour info, j'appelle cette procédure au moment du formcreate et non du formshow ce qui améliore déjà les performances mais ça n'est pas encore satisfaisant.

    Merci d'avance pour vos conseils et vos idées.

    LaNono

  2. #2
    Membre expert
    Avatar de pprem
    Homme Profil pro
    MVP Embarcadero - formateur&développeur Delphi, PHP et JS
    Inscrit en
    Juin 2013
    Messages
    1 876
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : MVP Embarcadero - formateur&développeur Delphi, PHP et JS
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2013
    Messages : 1 876
    Points : 3 611
    Points
    3 611
    Par défaut
    Si tu bosses sous FMX, tu devrais commencer par appeler BeginUpdate sur ta fiche et finir par EndUpdate. Ca évite que les composants se dessinent à chaque modif appliquée à leur style.

    En VCL il y a beaucoup de questions sur le sujet et plusieurs solutions dont celles-ci (pas testées, à toi de voir) :
    http://www.delphigroups.info/2/80/202463.html

    Tu peux aussi le faire sur chaque composant modifié en début et fin de modification (lorsqu'ils possèdent ces méthodes).

  3. #3
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 043
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 043
    Points : 40 957
    Points
    40 957
    Billets dans le blog
    62
    Par défaut
    Citation Envoyé par pprem Voir le message
    Si tu bosses sous FMX, tu devrais commencer par appeler BeginUpdate sur ta fiche et finir par EndUpdate.
    Puisque l'on voit sur le code des TAdvxxxx (composants TMS) il s'agit de VCL
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  4. #4
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 694
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 694
    Points : 13 130
    Points
    13 130
    Par défaut
    Le bloc try..except n'a pas de raison d'être. Le gestionnaire d'exception consomme du temps.

    Ajoute des else. Un composant ne peu pas être TAdvGlowButton ET TAdvStringGrid.
    Et par la même occasion, place ces blocs dans un ordre logique par rapport à la structure de ta fiche. S'il y a plus de labels que de boutons, test d'abord les labels.

  5. #5
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    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 : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut
    Pourquoi For I:=1 To MaForm_.ComponentCount Do et [I - 1] ?
    Autant faire For I:=0 To MaForm_.ComponentCount -1 Do et [I] !
    Bon, tu vas gagner quoi 1µs

    Comme tu le dit AndNotOr, une structure if else if else sera, un peu plus performante mais encore c'est des µs qui seront gagnés

    MaForm_.Components[I-1] pourrait être stocké dans TempCmpn dès la première de la boucle, cela évite des accès répétés à MaForm_.Components[I-1].

    OnCreate est un bon choix, comme il n'y a pas d'affichage, cela peut réduire le temps d'exécution par rapport au OnShow
    Sauf que si c'est valable pour des contrôles Windows pour des composants lourdissimes comme ceux de TMS, j'ai quelques doutes.

    La fonction SetComponentStyle ne provoquera pas un chargement de ressources ?
    Tu devrais mesurer les temps d'éxécution avec un TStopWatch pour voir ce qui consomme vraiment
    Par exemple une TAdvStringGrid déjà rempli (ou connecté à un DataSource), c'est peut-être plus lent à manipuler qu'une TAdvStringGrid encore vide

    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
    34
    35
    36
    37
    38
    39
    40
     
    Procedure ModifStyleFiche(MaForm_ : TForm);
    Var
      I : Integer;
      TempCmpn : TComponent;
     
    Begin
      if not Assigned(MaForm_) then
         Exit;
     
      MaForm_.Font.Size:=8;
      MaForm_.Color:=clWhite;
     
      for I:=0 To MaForm_.ComponentCount-1 do
      begin
        TempCmpn:=MaForm_.Components[I];
        if TempCmpn is TAdvGlowButton then       
        begin
     
          TAdvGlowButton(TempCmpn).SetComponentStyle(tsOffice2013White);
          TAdvGlowButton(TempCmpn).Appearance.BorderColor:=clBlack;
          TAdvGlowButton(TempCmpn).Appearance.BorderColorChecked:=$00FAFAFA;
          TAdvGlowButton(TempCmpn).Appearance.BorderColorDisabled:=clBlack;
          TAdvGlowButton(TempCmpn).Appearance.BorderColorDown:=clActiveCaption;
          //...
        end
        else if TempCmpn is TAdvStringGrid then
        begin
          TAdvStringGrid(TempCmpn).Ctl3D:=False;
          TAdvStringGrid(TempCmpn).FixedColor:=clWhite;
          TAdvStringGrid(TempCmpn).FixedFont.Color:=clNavy;
          TAdvStringGrid(TempCmpn).FixedFont.Style:=[];
          TAdvStringGrid(TempCmpn).ControlLook.FixedGradientFrom:=clWhite;
          TAdvStringGrid(TempCmpn).ControlLook.FixedGradientTo:=clWhite;
        end
        else if TempCmpn is TTruc then
        // 
      End;
     
    End;
    On va éviter le with pour le moment mais l'accès à TAdvGlowButton(TempCmpn).Appearance ou TAdvStringGrid(TempCmpn).ControlLook est-il complexe avec les accesseurs ?
    Encore des µs à gagner à chaque appel
    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

  6. #6
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 694
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 694
    Points : 13 130
    Points
    13 130
    Par défaut
    Et une boucle sur ControlCount évidemment. Les composants non visuels n'ont pas besoin d'être énumérés

  7. #7
    Membre émérite

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 388
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 388
    Points : 2 999
    Points
    2 999
    Par défaut
    Je vais peut-être dire une sottise mais le cast est-il utile sur chaque ligne ?
    Pointer une seule fois sur l'objet "casté" n'est-il pas un poil plus rapide ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    with (MaForm_.Components[I-1]) do
    begin
      SetComponentStyle(tsOffice2013White);
      Appearance.BorderColor:=clBlack;
      Appearance.BorderColorChecked:=$00FAFAFA;
      Appearance.BorderColorDisabled:=clBlack;
      Appearance.BorderColorDown:=clActiveCaption;
    end;
    et http://docwiki.embarcadero.com/Libra...hreading.TTask ça n'aiderait pas ?

  8. #8
    Membre expert
    Avatar de pprem
    Homme Profil pro
    MVP Embarcadero - formateur&développeur Delphi, PHP et JS
    Inscrit en
    Juin 2013
    Messages
    1 876
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : MVP Embarcadero - formateur&développeur Delphi, PHP et JS
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2013
    Messages : 1 876
    Points : 3 611
    Points
    3 611
    Par défaut
    Citation Envoyé par Papy214 Voir le message
    Je vais peut-être dire une sottise mais le cast est-il utile sur chaque ligne ?
    Pointer une seule fois sur l'objet "casté" n'est-il pas un poil plus rapide ?
    Le compilateur est censé s'en débrouiller, donc il ne devrait pas y avoir d'impact à l'utilisation mais effectivement c'est mieux de l'écrire avec un Withou de créer une variable locale du bon type et lui affecter l'objet en question.

    Citation Envoyé par Papy214 Voir le message
    Comme c'est un problème de composants visuels et que ça doit se faire lors de la création de la fiche, il est préférable d'éviter les processus car l'opération doit se faire avant l'affichage de la fiche, donc il faudrait faire une boucle d'attente sur le thread pour ça. A la limite un TParallel.for() mais il y a un risque car qui dit composant visuel, dit aussi problème de synchro avec le thread principal pour l'affichage.

  9. #9
    Membre régulier
    Femme Profil pro
    Inscrit en
    Avril 2007
    Messages
    209
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Suisse

    Informations forums :
    Inscription : Avril 2007
    Messages : 209
    Points : 93
    Points
    93
    Par défaut
    Bonjour à tous et un grand merci pour votre réactivité.

    Malheureusement les solutions proposées ne font pas gagné autant que je l'avais espéré. Par contre, en investiguant plus loin, il s'avère que le plus gros mangeur de temps est la redimension des boutons situés sur les ToolBars. Il semble qu'ils se repositionnent à chaque fois.

    Du coup j'ai dû ajouter le code suivant en début de procédure :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
            For I:=1 To FormFiche.ComponentCount Do
            If FormFiche.Components[I-1] is TAdvToolBar Then
            Begin
                 TAdvToolBar(FormFiche.Components[I-1]).AutoSize:=False;
                 TAdvToolBar(FormFiche.Components[I-1]).DisableAlign;
            End;
    Et réactiver à la fin et je garde 1.5 secondes. c'est déjà ça. Je creuse encore pour la suite.

    Merci à tous.

    LaNono

  10. #10
    Membre expert
    Avatar de pprem
    Homme Profil pro
    MVP Embarcadero - formateur&développeur Delphi, PHP et JS
    Inscrit en
    Juin 2013
    Messages
    1 876
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : MVP Embarcadero - formateur&développeur Delphi, PHP et JS
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2013
    Messages : 1 876
    Points : 3 611
    Points
    3 611
    Par défaut
    Combien as-tu de composants sur tes fiches pour perdre autant de temps dessus ?
    As-tu essayé de contacter TMS Software pour discuter de ce problème avec eux au cas où des améliorations soient possibles sur leurs composants ?

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

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

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 445
    Points
    28 445
    Par défaut
    STOP ! on arrête tout ces horreurs et on fait de la POO

    en supposant que TAdvGlowButton soit déclaré dans l'unité AdvGlowButton.pas

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    unit Unit1;
     
    interface
     
    uses
      AdvGlowButton,...., CustomTMS;
     
    type
      TForm1 = class(TForm)
        AdvGlowButton1: TAdvGlowButton;
      end;
    et dans CustomTMS

    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
     
    unit CustomTMS;
     
    interface
     
    uses
      AdvGlowButton;
     
    type
      TAdvGlowButton = class(AdvGlowButton.TAdvGlowButton)
      public
        constructor Create(AOwner: TComponent); override;
      end;
     
    implementation
     
    constructor TAdvGlowButton.Create(AOwner: TComponent);
    begin
      inherited;
      SetComponentStyle(tsOffice2013White);
      Appearance.BorderColor:=clBlack;
      Appearance.BorderColorChecked:=$00FAFAFA;
      Appearance.BorderColorDisabled:=clBlack;
      Appearance.BorderColorDown:=clActiveCaption;
    ...
    end;
     
    end.
    avec ça, il suffit d'ajouter l'unité CustomTMS en fin de Uses de chaque fiche et le tour est joué.
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  12. #12
    Membre régulier
    Femme Profil pro
    Inscrit en
    Avril 2007
    Messages
    209
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Suisse

    Informations forums :
    Inscription : Avril 2007
    Messages : 209
    Points : 93
    Points
    93
    Par défaut
    Salut Paul Toth, merci beaucoup pour ta solution.

    J'avais pensé à cette solution mais (avec un peu de flemmardise )je voulais m'éviter de tout re-déclarer.

    Je vais faire un essai avec ça.

    Merci à tous pour votre grande aide.

    LaNono

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

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

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 445
    Points
    28 445
    Par défaut
    au passage, tu peux même - si tu n'utilises pas les propriétés avancées de ces composants - placer de simples TButton sur la fiche que tu surcharges en TAdvGlowButton dans CustomTMS.pas, ce qui permet au projet de pouvoir être ouvert sans problème sur un Delphi qui ne posséderait pas les composants TMS
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

Discussions similaires

  1. [Débutant] Afficher le code d'initialisation des composants
    Par noftal dans le forum Visual Studio
    Réponses: 6
    Dernier message: 12/09/2013, 20h48
  2. For each sur Composant ? Initialiser des composants.
    Par 19cmos83 dans le forum Interfaces Graphiques en Java
    Réponses: 8
    Dernier message: 11/10/2007, 11h02
  3. Réponses: 4
    Dernier message: 09/10/2007, 09h00
  4. Optimisation temps d'accès Bdd des composants ADO
    Par Creenshaw dans le forum Bases de données
    Réponses: 14
    Dernier message: 07/06/2005, 17h09
  5. Réponses: 1
    Dernier message: 02/01/2003, 12h45

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