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

C++Builder Discussion :

Lenteur dans un TTreeView


Sujet :

C++Builder

  1. #1
    Membre averti
    Inscrit en
    Mars 2009
    Messages
    41
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 41
    Par défaut Lenteur dans un TTreeView
    Bonjour, donc comme le titre l'indique le post va traiter d'un soucis de lenteur
    dans le TTreeView en effet je travaille sur un outil de lecture de fichier que je
    rebalance dans un arbre. Mon soucis et que la construction de l'arbre me prend environ 2 bonnes grosses minutes. Après quelque recherche je suis tombé sur 2 solutions l'utilisation de BeginUpdate et EndUpdate et l'envoie du message WM_SETREDRAW pour empécher le refresh a chaque ajout de noeud.
    Mais sans résultat en effet le temps de construction varie de 1 ou 2 secondes avec ces solutions.

    Ca viens peut être de l'utilisation des fonctions donc je vous expose mon Code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    tv->Visible = false;
    tv->Items->BeginUpdate();
    tv->Perform(WM_SETREDRAW,0,0);
    _gestionLectureEDI->LireFichierEDI(edChemin->Text);
    _gestionLectureEDI->ConstruireArbre(tv);
    tv->Perform(WM_SETREDRAW,1,0);
    tv->Items->EndUpdate();
    tv->Visible = true;
    Pas besoin de commentaire pour designer la fonction qui construit l'arbre...

    Voila si vous avez une idée je suis en panne d'inspiration pour le moment.

  2. #2
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 081
    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 081
    Par défaut
    Tu crées combien de noeud ?
    Effectivement BeginUpdate\EndUpdate, c'est une très bonne pratique
    Pour le WM_SETREDRAW, c'est inutile, en regardant le code de BeginUpdate, tu aurais vu que c'est la même solution

    Code pascal : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    procedure TTreeNodes.BeginUpdate;
    begin
      if FUpdateCount = 0 then
        SetUpdateState(True);
      Inc(FUpdateCount);
    end;
     
    procedure TTreeNodes.SetUpdateState(Updating: Boolean);
    begin
      SendMessage(Handle, WM_SETREDRAW, Ord(not Updating), 0);
      if not Updating then
        Owner.Refresh;
    end;

    As-tu essayé de constuire autant de noeud que tu en prévois pour ton fichier mais dans une fonction de debug, juste de la création en masse, pour mesurer le temps ?

    J'ai codé en Delphi, il y a 10 ans, un editeur de base de registre, il fonctionne encore, ça met 2s pour créer 5000 noeuds (juste les enfants de 1er Niveau de HKEY_CLASSE_ROOT), plus un noeud fantome pour les enfants de 2nd niveau (pour faire apparaître le + car je ne savais pas que l'on pouvait modifier HasChildren )
    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

  3. #3
    Membre expérimenté

    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    288
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Janvier 2003
    Messages : 288
    Par défaut
    2 secondes pour 5000! J'ai un TreeView qui est assez lent, du coup je suis en train de revoir le code

    nazgul66:
    Dans ton code LireFichierEDI prends aussi une partie du temps de traitement et cela n'a rien a voir avec le TreeView.
    Ensuite tout dépends comment tu énumère les noeuds dans ConstruireArbre.

    Tout ce que je peux dire c'est que l'énumération avec getFirstChild/GetNextChild & getNextSibling est beaucoup plus performante que si tu utilise une boucle for (avec Count et Item[]).
    Aussi si tu as des noeuds récurrents (sur lesquels tu fait des opérations répétées) mémorise les, cela t'évitera de les rechercher.

    EDIT: etant donné que je suis en train de revoir mon code, je suis tombé sur un de mes commentaires: évite d'utiliser Expand au fur et à mesure que tu alimente le TreeView.

  4. #4
    Membre averti
    Inscrit en
    Mars 2009
    Messages
    41
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 41
    Par défaut
    Merci pour vos 2 réponses donc pour répondre à yarp je n'utilise pas Expand.

    Pour la construction de mon arbre j'utilse la fonction AddChild et je descend au max à 5 niveaux de noeuds pour environ 15000 items ajoutés. Pour tester j'ai enlevé les ajouts de noeuds et j'ai aissé le traitement des données dans la fonction qui construit l'arbre et je passe de 2min15 de traitement a 5 secondes donc même si les traitements qui ne concerne pas l'arbre ne sont pas instantanés ils sont négligeables.

    Je vais tester si l'ajout de 15000 noeuds de niveau 0 et 15000 qui descende sur 5 niveaux et voir un peu ce que ça donne.

    Effectivement je viens de faire le test avec 15000 noeuds et c'est quasiment instantanée dans les 2 cas. Je vais continuer de creuser pour trouver pourquoi dans mon cas s'est aussi long.

  5. #5
    Membre averti
    Inscrit en
    Mars 2009
    Messages
    41
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 41
    Par défaut
    Donc pour finir j'ai eu le dernier mot, donc le problème est que pour une raison obscure j'avais une fonction qui me permettait de récupérer le dernier noeud ajouté à partir d'un niveau donné. Et il a pas l'air d'apprécier la blague.
    Donc pour ma part c'est résolu.

    Merci ShaiLeTroll et yarp.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Drag and drop dans un TTreeView
    Par BigBenQ dans le forum C++Builder
    Réponses: 3
    Dernier message: 07/10/2005, 14h57
  2. Access violation dans un TTreeView
    Par Vulcanos dans le forum Composants VCL
    Réponses: 1
    Dernier message: 13/09/2005, 03h58
  3. Comment passer en mode édition dans un TTreeView ?
    Par Invité dans le forum C++Builder
    Réponses: 6
    Dernier message: 08/08/2005, 13h37
  4. Réponses: 1
    Dernier message: 31/07/2005, 17h44
  5. Couleur du texte d'un TTreeNode dans un TTreeview
    Par Vulcanos dans le forum Composants VCL
    Réponses: 5
    Dernier message: 18/02/2005, 18h50

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