OVH Cloud OVH Cloud

charger un flexgrid

12 réponses
Avatar
F. David
Bonjour,

Je dois remplir un flexgrid à partir de données présentes dans un fichier
texte avec séparateur.
Le problème, c'est que le fichier à charger peut être assez gros (maximum
10Mo) et le chargement prend un temps fou : 12s pour 6 Mo
Pour remplir le tableau j'utilise cette fonction qui marche très bien mais
qui rame quand même pas mal :
http://groups.google.fr/groups?hl=fr&lr=&rls=GGLD,GGLD:2004-51,GGLD:fr&selm=O8AEg53fCHA.1860%40tkmsftngp09&rnum=7

J'ai fait des essais toujours avec la même fonction à peine modifiée avec un
autre contrôle (vbalgrid de VBAccelerator) et les temps de chargement sont
encore pire ! Comme quoi le temps de chargement ne dépend pas que de notre
code.

Pourtant, je vois des applications qui chargent 2000 lignes dans ce type de
contrôle en un clin d'oeil. Mais comment font-il ? ;-) Je doute que ce soit
en VB où alors je ne sais pas m'y prendre et il existe une astuce ou une
autre façon de faire ?

Toute aide sera la bienvenue ... Merci
--
Franck

10 réponses

1 2
Avatar
Jean-Marc
"F. David" a écrit dans le message de
news:
Bonjour,

Je dois remplir un flexgrid à partir de données présentes dans un fichier
texte avec séparateur.
Le problème, c'est que le fichier à charger peut être assez gros (maximum
10Mo) et le chargement prend un temps fou : 12s pour 6 Mo
Pour remplir le tableau j'utilise cette fonction qui marche très bien mais
qui rame quand même pas mal :



http://groups.google.fr/groups?hl=fr&lr=&rls=GGLD,GGLD:2004-51,GGLD:fr&selm=O8AEg53fCHA.1860%40tkmsftngp09&rnum=7

J'ai fait des essais toujours avec la même fonction à peine modifiée avec


un
autre contrôle (vbalgrid de VBAccelerator) et les temps de chargement sont
encore pire ! Comme quoi le temps de chargement ne dépend pas que de notre
code.

Pourtant, je vois des applications qui chargent 2000 lignes dans ce type


de
contrôle en un clin d'oeil. Mais comment font-il ? ;-) Je doute que ce


soit
en VB où alors je ne sais pas m'y prendre et il existe une astuce ou une
autre façon de faire ?



Hello,

il y a des solutions, mais cela va dépendre de différents paramètres.
Peux tu donner quelques précisions et notamment ceci:
- Combien de lignes environ dans ton fichier de 10 Mo ?
- Combien de champs par ligne ? (combien de séparateurs environ)

Une fois ceci connu, il sera plus facile de proposer une solution.

Enfin, les pistes évidentes:
Il serait très utile de mesurer le temps, sur un même gros fichier:
- en faisant le découpage mais SANS insérer dans le Flexgrid
- en faisant le découpage ET en insérerant dans le Flexgrid

Ca permettra d'identifier l'endroit ou le temps est consommé.

On pourra alors essayer différentes choses:
- faire l'insertion avec le flexgrid disable
- faire l'insertion avec le flexgrid visibleúlse
- tenter une lecture du fichier en un ou plusieurs
appels en binaire et non plus ligne par ligne
- etc...

Ca va dépendre des infos complémentaires que tu pourras donner.

--
Jean-marc
"There are only 10 kind of people
those who understand binary and those who don't."
Avatar
Jean-Marc
"F. David" a écrit dans le message de
news:
Bonjour,

Je dois remplir un flexgrid à partir de données présentes dans un fichier
texte avec séparateur.
Le problème, c'est que le fichier à charger peut être assez gros (maximum
10Mo) et le chargement prend un temps fou : 12s pour 6 Mo
Pour remplir le tableau j'utilise cette fonction qui marche très bien mais
qui rame quand même pas mal :



http://groups.google.fr/groups?hl=fr&lr=&rls=GGLD,GGLD:2004-51,GGLD:fr&selm=O8AEg53fCHA.1860%40tkmsftngp09&rnum=7

J'ai fait des essais toujours avec la même fonction à peine modifiée avec


un
autre contrôle (vbalgrid de VBAccelerator) et les temps de chargement sont
encore pire ! Comme quoi le temps de chargement ne dépend pas que de notre
code.

Pourtant, je vois des applications qui chargent 2000 lignes dans ce type


de
contrôle en un clin d'oeil. Mais comment font-il ? ;-) Je doute que ce


soit
en VB où alors je ne sais pas m'y prendre et il existe une astuce ou une
autre façon de faire ?



J'ai regardé aussi le code que tu donnes en exemple dans
le lien.
Même si ca ne suffit pas, il peut être amélioré ne serait
ce qu'en sortant de la boucle while le test qui vérifie
le nombre de colonnes. En effet, si tu connais ton format
d'entrée et que toutes les lignes ont le même nombre de
champs,
il est plus malin de faire l'init une seule fois au début
en comptant le nombre de champs dans la première lignes
que de retester à chaque fois dans le corps de la boucle.

De même, l'incrémentation du nombre de lignes peut être
fait à moindre cout et en évitant un test systématique, juste
en arrangeant un peux mieux le code sans en changer le principe.

Bref, il y a plein de temps à gagner, à droite ou à gauche.

Bien sur, tout cela n'a de sens que si on identifie d'abord les
endroits ou il faut *vraiment* gagner du temps:
Si on passe 10% du temps à découper et 90% du temps à insérer
dans le flexgrid, il est un peu bête de vouloir optimiser le
découpage.

--
Jean-marc
"There are only 10 kind of people
those who understand binary and those who don't."
Avatar
F. David
Jean-Marc wrote:
"F. David" a écrit dans le message de
news:



Je dois remplir un flexgrid à partir de données présentes dans un
fichier
texte avec séparateur.
Le problème, c'est que le fichier à charger peut être assez gros
(maximum 10Mo) et le chargement prend un temps fou : 12s pour 6 Mo
Pour remplir le tableau j'utilise cette fonction qui marche très
bien mais qui rame quand même pas mal :






il y a des solutions, mais cela va dépendre de différents paramètres.



Bonjour et merci pour le coup de main si rapide.:-)

Peux tu donner quelques précisions et notamment ceci:
- Combien de lignes environ dans ton fichier de 10 Mo ?
- Combien de champs par ligne ? (combien de séparateurs environ)



Pour l'instant, je me base juste sur un fichier de 6Mo qui fait 2256 lignes
avec 5 séparateurs par ligne et donc 6 champs.
J'aimerais qu'un fichier puisse accueillir au maximum 5000 lignes ce qui
nous ferait un poids dans les 10 même plutôt 12 -13 Mo.

Une fois ceci connu, il sera plus facile de proposer une solution.

Enfin, les pistes évidentes:
Il serait très utile de mesurer le temps, sur un même gros fichier:
- en faisant le découpage mais SANS insérer dans le Flexgrid
- en faisant le découpage ET en insérerant dans le Flexgrid



Donc j'ai fait le test pour ce fichier de 2256 lignes.
J'ai juste mis un timeGetTime() en début (d) et en fin (f) de code.

SANS : f-d = 1406

AVEC : f-d = 9422

Ca permettra d'identifier l'endroit ou le temps est consommé.



On pourra alors essayer différentes choses:
- faire l'insertion avec le flexgrid disable
- faire l'insertion avec le flexgrid visibleúlse
- tenter une lecture du fichier en un ou plusieurs
appels en binaire et non plus ligne par ligne
- etc...

Ca va dépendre des infos complémentaires que tu pourras donner.



J'ai déjà essayé la solution de masquer la grille avant et de la réafficher
après : pas de changement notoire. Idem avec la propriété enabled à false
puis à true avant et après l'insertion.
Ensuite, pour les appels multiples en binaire, je veux bien essayer mais je
ne sais pas faire ...
Merci pour tout aide.

--
Franck
Avatar
Jean-Marc
Re hello,

ok, j'ai fait des tests avec un fichier de 5000 lignes, 7 champs
Resultats:

J'ai utilisé la fonction telle qu'à l'origine:
=> 9 secondes
J'ai modifié cette fonction pour enlever les
trucs inutiles en plein milieu de la boucle:
=> 8 secondes

Mon flexgrid s'appelle msg1;
si je fais
msg1.visible = FALSE
call la fonction
msg1.visible = TRUE
=> 5 secondes

Enfin, j'ai supprimé du code les 2 instructions:

mshfg.Rows = mshfg.Rows + 1
et
mshfg.TextMatrix(mshfg.Rows - 1, i) = sDonnees(i - 1)

pour ne mesurer que le temps de lecture du fichier
et de split des données:
=> 0,1 seconde.

Tu as ta réponse donc:

Tu peux gagner un petit peu en utilisant la fonction améliorée.
Tu regagnes en faisant un visibleúLSE avant l'appel (gain de 50%)

Tu ne gagnerais rien à essayer d'optimiser la lecture ou le découpage.

Tout le temps est consommé par
mshfg.Rows = mshfg.Rows + 1 et par
mshfg.TextMatrix(mshfg.Rows - 1, i) = sDonnees(i - 1)

J'ai enlevé ensuite uniquement l'affectation
mshfg.TextMatrix(mshfg.Rows - 1, i) = sDonnees(i - 1)

en ne gardant donc que le
mshfg.Rows = mshfg.Rows + 1

résultat = 4, 9

Conclusion: tout le temps est consommé dans
mshfg.Rows = mshfg.Rows + 1

voila voila...


--
Jean-marc
"There are only 10 kind of people
those who understand binary and those who don't."
"F. David" a écrit dans le message de
news:
Jean-Marc wrote:
> "F. David" a écrit dans le message de
> news:

>> Je dois remplir un flexgrid à partir de données présentes dans un
>> fichier
>> texte avec séparateur.
>> Le problème, c'est que le fichier à charger peut être assez gros
>> (maximum 10Mo) et le chargement prend un temps fou : 12s pour 6 Mo
>> Pour remplir le tableau j'utilise cette fonction qui marche très
>> bien mais qui rame quand même pas mal :


> il y a des solutions, mais cela va dépendre de différents paramètres.

Bonjour et merci pour le coup de main si rapide.:-)

> Peux tu donner quelques précisions et notamment ceci:
> - Combien de lignes environ dans ton fichier de 10 Mo ?
> - Combien de champs par ligne ? (combien de séparateurs environ)

Pour l'instant, je me base juste sur un fichier de 6Mo qui fait 2256


lignes
avec 5 séparateurs par ligne et donc 6 champs.
J'aimerais qu'un fichier puisse accueillir au maximum 5000 lignes ce qui
nous ferait un poids dans les 10 même plutôt 12 -13 Mo.

> Une fois ceci connu, il sera plus facile de proposer une solution.
>
> Enfin, les pistes évidentes:
> Il serait très utile de mesurer le temps, sur un même gros fichier:
> - en faisant le découpage mais SANS insérer dans le Flexgrid
> - en faisant le découpage ET en insérerant dans le Flexgrid

Donc j'ai fait le test pour ce fichier de 2256 lignes.
J'ai juste mis un timeGetTime() en début (d) et en fin (f) de code.

SANS : f-d = 1406

AVEC : f-d = 9422

> Ca permettra d'identifier l'endroit ou le temps est consommé.

> On pourra alors essayer différentes choses:
> - faire l'insertion avec le flexgrid disable
> - faire l'insertion avec le flexgrid visibleúlse
> - tenter une lecture du fichier en un ou plusieurs
> appels en binaire et non plus ligne par ligne
> - etc...
>
> Ca va dépendre des infos complémentaires que tu pourras donner.

J'ai déjà essayé la solution de masquer la grille avant et de la


réafficher
après : pas de changement notoire. Idem avec la propriété enabled à false
puis à true avant et après l'insertion.
Ensuite, pour les appels multiples en binaire, je veux bien essayer mais


je
ne sais pas faire ...
Merci pour tout aide.

--
Franck



Avatar
Jean-Marc
"Jean-Marc" a écrit dans le message de
news:423bf222$0$20667$
Re hello,

ok, j'ai fait des tests avec un fichier de 5000 lignes, 7 champs
Resultats:
Conclusion: tout le temps est consommé dans
mshfg.Rows = mshfg.Rows + 1



Re coucou,


Du coup, ayant identifié la nature du problème,
il ne restait qu'à le résoudre.
Très simple:
- on compte le nombre de lignes
- on prédimensionne le flexgrid
- on remplit tranquillemnt

***********************************************
Resultat = > les 5000 lignes en 0,7 secondes !
Au lieu de 9 secondes initialement!
***********************************************
voici le code:

Private Sub FileToGrid_OPT(ByRef sFile As String, _
ByRef mshfg As MSHFlexGrid, _
ByRef sSeparateur As String)
Dim sLigne As String
Dim sDonnees() As String
Dim i As Integer
Dim f As Integer
Dim nbl As Long
Dim n As Long

' on compte les lignes
f = FreeFile
Open sFile For Input As #f
While Not EOF(f)
Line Input #f, sLigne
nbl = nbl + 1
Wend
Close #f
' on initialise le flex
mshfg.Rows = nbl

' on fait une petite lecture de une ligne pour calculer les colonnes
f = FreeFile
Open sFile For Input As #f
Line Input #f, sLigne
sDonnees = Split(sLigne, sSeparateur)
'Vérifie si le nombre de colonnes à été initialisé
If mshfg.Cols <> UBound(sDonnees) + 2 Then
'Initialise le nombre de colonne
mshfg.Cols = UBound(sDonnees) + 2
End If
Close #f

' et maintenant on y va
sLigne = ""
f = FreeFile
Open sFile For Input As #f
Do While Not EOF(f)
Line Input #f, sLigne
sDonnees = Split(sLigne, sSeparateur)
' on incrémente la position ici
n = n + 1
For i = 1 To mshfg.Cols - 1
mshfg.TextMatrix(n - 1, i) = sDonnees(i - 1)
Next
Loop
Close #f
End Sub

et l'appel:
Dim t1 As Double
Dim t2 As Double

t1 = Timer
msg1.Visible = False
Call FileToGrid_OPT("c:std_v3datagiexp2.tab", msg1, vbTab)
msg1.Visible = True
t2 = Timer
MsgBox "fini en " & t2 - t1 & " secondes"


Bonne journée !

--
Jean-marc
"There are only 10 kind of people
those who understand binary and those who don't."
Avatar
F. David
Jean-Marc wrote:

J'ai regardé aussi le code que tu donnes en exemple dans
le lien.
Même si ca ne suffit pas, il peut être amélioré ne serait
ce qu'en sortant de la boucle while le test qui vérifie
le nombre de colonnes. En effet, si tu connais ton format
d'entrée et que toutes les lignes ont le même nombre de
champs,
il est plus malin de faire l'init une seule fois au début
en comptant le nombre de champs dans la première lignes
que de retester à chaque fois dans le corps de la boucle.



Pas de souci à ce niveau là, je ne m'étais fait la même remarque et j'avais
déjà supprimé cette partie étant donné que mes colonnes sont déjà
initialisées avant l'opération de chargement.

De même, l'incrémentation du nombre de lignes peut être
fait à moindre cout et en évitant un test systématique, juste
en arrangeant un peux mieux le code sans en changer le principe.

Bref, il y a plein de temps à gagner, à droite ou à gauche.

Bien sur, tout cela n'a de sens que si on identifie d'abord les
endroits ou il faut *vraiment* gagner du temps:
Si on passe 10% du temps à découper et 90% du temps à insérer
dans le flexgrid, il est un peu bête de vouloir optimiser le
découpage.



Effectivement et je crois que nous sommes vraiment dans ces proportions !
C'est vraiment l'opération d'insertion proprement dite qui ralentit le
processus.

--
Franck
Avatar
F. David
Jean-Marc wrote:
"Jean-Marc" a écrit dans le message
de news:423bf222$0$20667$
Re hello,

ok, j'ai fait des tests avec un fichier de 5000 lignes, 7 champs
Resultats:
Conclusion: tout le temps est consommé dans
mshfg.Rows = mshfg.Rows + 1



Re coucou,


Du coup, ayant identifié la nature du problème,
il ne restait qu'à le résoudre.
Très simple:
- on compte le nombre de lignes
- on prédimensionne le flexgrid
- on remplit tranquillemnt

***********************************************
Resultat = > les 5000 lignes en 0,7 secondes !
Au lieu de 9 secondes initialement!
***********************************************



Alors là franchement je suis épaté ;-)
Belle démonstration et comme quoi, comme on disait à l'armée, il n'y a
jamais de problème mais que des solutions ;-)
Je vais tester cela de ce pas ...

Un grand merci !
--
Franck
Avatar
Jean-Marc
Voici le code final avec une petite modification.

Les performance sont finalement de 0,58 contre 9
initialement.

Private Sub FileToGrid_OPT(ByRef sFile As String, _
ByRef mshfg As MSHFlexGrid, _
ByRef sSeparateur As String)
Dim sLigne As String
Dim sDonnees() As String
Dim i As Long, nbl As Long
Dim f As Integer
Dim nCol As Long

' Compte le nombre de lignes
f = FreeFile
Open sFile For Input As #f
While Not EOF(f)
Line Input #f, sLigne
nbl = nbl + 1
Wend
Close #f
' Initialisation du nombre de lignes dans le flexgrid
mshfg.Rows = nbl + 1

' Lecture de 1 ligne pour calculer le nombre de colonnes
f = FreeFile
Open sFile For Input As #f
Line Input #f, sLigne
sDonnees = Split(sLigne, sSeparateur)
mshfg.Cols = UBound(sDonnees) + 2
Close #f
nCol = mshfg.Cols

nbl = 0
' Remplissage du flexgrid
f = FreeFile
Open sFile For Input As #f
Do While Not EOF(f)
Line Input #f, sLigne
sDonnees = Split(sLigne, sSeparateur)
' calcul la position
nbl = nbl + 1
For i = 1 To nCol - 1
mshfg.TextMatrix(nbl, i) = sDonnees(i - 1)
Next
Loop
Close #f
End Sub

--
Jean-marc
"There are only 10 kind of people
those who understand binary and those who don't."
Avatar
F. David
Jean-Marc wrote:
Voici le code final avec une petite modification.

Les performance sont finalement de 0,58 contre 9
initialement.



J'ai pu tester et je confirme une très nette amélioration du temps de
traitement. Ici je suis un peu au dessus (proche des deux secondes) car je
n'ai pas une machine ultra-puissante mais je dirais que ce n'est pas plus
mal car ça me permet de détecter de telles anomalies au niveau du temps
d'exécution. Donc oui, y'a pas photo, c'est le jour et la nuit entre le code
initial et celui-ci !

Encore merci et bonne journée
--
Franck
Avatar
F. David
F. David wrote:
Jean-Marc wrote:
Voici le code final avec une petite modification.

Les performance sont finalement de 0,58 contre 9
initialement.



J'ai pu tester et je confirme une très nette amélioration du temps de
traitement. Ici je suis un peu au dessus (proche des deux secondes)
car je n'ai pas une machine ultra-puissante mais je dirais que ce
n'est pas plus mal car ça me permet de détecter de telles anomalies
au niveau du temps d'exécution. Donc oui, y'a pas photo, c'est le
jour et la nuit entre le code initial et celui-ci !



En fait, je viens de me rendre compte que j'obtiens un peu plus car je
charge dans un vbalgrid et non dans un flexgrid. Les perfomances sont
meilleures dans un flexgrid indépendamment du code utilisé.
--
Franck
1 2