Membres inscrits :2359
Membres en ligne : 0
Invités en ligne : 5


|
Conversation : wxGrid : lenteurs d'execution |
milope (Membre)
Inscrit le : 07-01-2010
Messages: 34
Snippets: 0
Tutoriels: 0
Hors ligne |
Bonjour,
Je fait face à un soucis de taille : ma wxgrid lag à mort !
Le remplissage (environ 100 colonnes et 1000 lignes) dure quelques longues minutes :s
Code Cpp: (...) for (int iNoLigne = 0; iNoLigne < iNoLigne; iNoLigne++) RemplirSpread(iNoLigne);
Code Cpp:int FrameGrille::RemplirSpread(int iNoLigne) { string str; bool bCelluleVide = false; /// met bCelluleVide a true si donnee == 0 -> cellule vide Grid1->AppendRows(1, true); Grid2->AppendRows(1, true); int iNbrLignes = Grid1->GetNumberRows() - 1; /// pour chaques colonnes for (int j = 0; j < iNombreColonneARemplir; j++) { switch (j + 1) { case 1: str = structLigne[iNoLigne].cData1; break; case 2: str = structLigne[iNoLigne].cData2; break; (...etc...) case 99: if (structLigne[iNoLigne].dData99 == 0.0) bCelluleVide = true; else str = DoubleToString(structLigne[iNoLigne].dData99); break; case 100: if (structLigne[iNoLigne].dData100 == 0.0) bCelluleVide = true; else str = DoubleToString(structLigne[iNoLigne].dData100); break; } structLigne[iNoLigne].iLigneSpread = iNbrLignes; ///renseigne le no de la ligne dans la structure /// si colonne fait partie de la grille 1 if (j < iNombreColonneARemplir_Grid1) { if (bCelluleVide == true) { Grid1->SetCellBackgroundColour(iNbrLignes, j, *wxLIGHT_GREY); bCelluleVide = false; } else Grid1->SetCellValue(iNbrLignes, j, stdStringToWxString(str)); Grid1->SetReadOnly(iNbrLignes, j, true); /// les données de la grille1 ne sont pas modifiables } /// si colonne fait partie de la grille 2 else { if (bCelluleVide == true) { Grid2->SetCellBackgroundColour(iNbrLignes, j-iNombreColonneARemplir_Grid1, *wxLIGHT_GREY); Grid2->SetCellValue(iNbrLignes, j-iNombreColonneARemplir_Grid1, _(" ")); Grid2->SetReadOnly(iNbrLignes, j-iNombreColonneARemplir_Grid1, true); bCelluleVide = false; } else Grid2->SetCellValue(iNbrLignes, j-iNombreColonneARemplir_Grid1, stdStringToWxString(str)); } } return 0; }
J'ai ouie dire que wxGridTableBase pourrait accelerer les choses, mais la doc fait cruellement défaut... Une idée pour accélérer tout cela ?
Merci ! ---------- Je pense à une astuce que nous avions utilisés, mais avec un autre tableur : serait-il possible de désactiver l'affichage pendant le traitement ?
Dernière modification par milope (14-10-2010 17:26:49)
|
C::B 10.05 wx 2.8.10 (unicode), Linux et MinGW 2 Intel Xeon 3GHz, 2G ram sous Ubuntu 10.04
|
Xaviou (Administrateur)
Lieu: Annecy (74)
Inscrit le : 27-08-2007
Messages: 1390
Snippets: 25
Tutoriels: 6
Site web
Hors ligne |
Salut.
A mon avis, wxWindowUpdateLocker devrait faire l'affaire.
@+ Xav'
|
Le nouveau portail wxWidgets francophone : www.wxdev.fr Ben en fait, vous y êtes déjà ... et effectivement, depuis le temps, ce n'est plus tellement nouveau....
|
milope (Membre)
Inscrit le : 07-01-2010
Messages: 34
Snippets: 0
Tutoriels: 0
Hors ligne |
Bonjour,
wxWindowUpdateLocker ne suffit pas :s
En fait c'est le fait de typer les cellules qui pose probleme :
Code Cpp:Grid2->SetCellBackgroundColour(iNbrLignes, j-iNombreColonneARemplir_Grid1, *wxLIGHT_GREY); Grid2->SetReadOnly(iNbrLignes, j-iNombreColonneARemplir_Grid1, true); Pour y pallier, j'ai donc utilisé une wxGridTableBase.
Code Cpp:attr = new wxGridCellAttr; ///wxGridCellAttr* attr; attr->SetReadOnly(true); attr->SetBackgroundColour(*wxLIGHT_GREY); Grid2_->SetAttr(attr, iNbrLignes, j-iNombreColonneARemplir_Grid1); ///wxGridTableBase* Grid2_; Grid2_->SetValue(iNbrLignes, j-iNombreColonneARemplir_Grid1, _("roti")); He be "roti" apparait bien dans ma grille, mais la cellule n'est ni grisée ni protegée en ecriture...
Une idée ?
|
C::B 10.05 wx 2.8.10 (unicode), Linux et MinGW 2 Intel Xeon 3GHz, 2G ram sous Ubuntu 10.04
|
etrange02 (Membre)
Lieu: Nantes
Inscrit le : 24-07-2009
Messages: 23
Snippets: 0
Tutoriels: 0
Site web
Hors ligne |
Tu peux essayer de faire de l'optimisation au niveau du langage, en choisissant bien tes types de variables.
Dans ta boucle, tu peux rajouter 'register int j' : ça place j dans un registre et c'est bien plus rapide d'accès que la RAM (Attention, on ne peut pas récupérer l'adresse !!)
Ensuite, ton switch est vraiment énorme ! Mais qu'est-ce qu'un switch ? Un switch est une écriture condensée de 'if else'. Une chose que tu peux faire est de le couper en 2 if : le premier inférieur à 50 et le reste dans le deuxième.
En espérant avoir apporter un morceau de la solution.
|
|
milope (Membre)
Inscrit le : 07-01-2010
Messages: 34
Snippets: 0
Tutoriels: 0
Hors ligne |
Merci pour ta réponse,
Mais comme dis dans mon précédent message, c'est après le switch que cela pose problème...
|
C::B 10.05 wx 2.8.10 (unicode), Linux et MinGW 2 Intel Xeon 3GHz, 2G ram sous Ubuntu 10.04
|
hx (Membre)
Inscrit le : 21-09-2010
Messages: 35
Snippets: 0
Tutoriels: 0
Hors ligne |
Salut,
Juste pour information tu peux me donner : - La version de wx, et compilé avec quoi (MinGW, VC, etc... ?) - Les caractéristiques principales de ta machine (CPU,RAM et OS)
Une petite remarque (désolé si c'est une bêtise je suis new en wx) ton "SetAttr", tu ne souhaiterais pas plutôt faire un "SetColAttr" ? (Voir bug potentiel ici http:/trac.wxwidgets.org/ticket/4401 )
Bon courage et tiens nous au courant, ton problème de lenteur m'intéresse beaucoup.
Hx
Dernière modification par hx (11-11-2010 12:19:04)
|
|
milope (Membre)
Inscrit le : 07-01-2010
Messages: 34
Snippets: 0
Tutoriels: 0
Hors ligne |
Ola hx,
Cf. signature pour infos. Mes essais sont systématiquement compilés pour Linux et Windows.
Présentement, j'essaye de typer par cellules et non par colonnes. Donc SetAttr.
Petit test en utilisant les fonctions de base de la wxGrid: - creer un projet frame based. - ajouter une wxGrid à la frame. - dans le constructeur de la frame, y coller ceci
Code Cpp:Grid1->CreateGrid(500, 100); for (int i = 0; i < 500; i++) { for (int j = 0; j < 100; j++) { Grid1->SetCellValue(i, j, _("essai")); Grid1->SetCellBackgroundColour(i, j, *wxLIGHT_GREY); Grid1->SetReadOnly(i, j, true); } } Cela devrait être super long à afficher, et ce à cause de SetCellBackgroundColour et de SetReadOnly. Il suffit de commenter ces deux lignes pour s'en rendre compte. ---------- Et un petit test utilisant wxGridTableBase (ce qui devrait accelerer le process) : - creer un projet frame based. - ajouter une wxGrid à la frame. - dans le constructeur de la frame, y coller ceci
Code Cpp:Grid1->CreateGrid(500, 100); wxGridTableBase* Grid1_ = Grid1->GetTable(); if (Grid1_->CanHaveAttributes()) { attr = new wxGridCellAttr; attr->SetReadOnly(true); attr->SetBackgroundColour(*wxLIGHT_GREY); for (int i = 0; i < 500; i++) for (int j = 0; j < 100; j++) { Grid1_->SetAttr(attr, i, j); Grid1_->SetValue(i, j, _("roti")); } } He ben cela accélère pas mal, mais le typage reste poussif. Pour le constater, il suffit de commenter la ligne "Grid1_->SetAttr(attr, i, j);" : le résultat est immédiat.
En conclusion, même en virtualisant la grille, le typage par cellule est super long :s
Et là j'ai besoin d'aide
Dernière modification par milope (15-11-2010 17:19:25)
|
C::B 10.05 wx 2.8.10 (unicode), Linux et MinGW 2 Intel Xeon 3GHz, 2G ram sous Ubuntu 10.04
|
|