Augmenter la rapidite d une boucle??? [Résolu]

peharant 9 Messages postés mercredi 18 octobre 2006Date d'inscription 4 novembre 2006 Dernière intervention - 1 nov. 2006 à 19:40 - Dernière réponse : peharant 9 Messages postés mercredi 18 octobre 2006Date d'inscription 4 novembre 2006 Dernière intervention
- 3 nov. 2006 à 16:29
bonsoir!

j ai un code qui split des fichiers textes et qui ensuite rentre les donnees dans des cellules excel.
voici le code

For k = 1 To 6


    For j = 200 * (k - 1) To 200 * k - 1 'do'
        Line Input #1, Line        'on met la valeur texte = la ligne
        NumLine = NumLine + 1          'augmenter
        Varline() = Split(Line, ",")
        For i = 0 To UBound(Varline)
            CF = Val(Varline(i))
            Worksheets("CF_Import_Data").Cells((k - 1) * 305 + 1, 1).Offset(i, j - 200 * (k - 1)).Value = CF
        Next i
        If EOF(1) = True Then GoTo previous
    Next j
Next k

le truc c que chaque ligne du fichier texte (correspondant a l input) contient 300 donnees.... et qu il y a plus de 1000 lignes!

est ce que qqun sait comment reduire le temps de calcul??????/

MERCI!
Afficher la suite 

Votre réponse

9 réponses

Meilleure réponse
MadM@tt 2215 Messages postés mardi 11 novembre 2003Date d'inscription 16 juillet 2009 Dernière intervention - 1 nov. 2006 à 20:15
3
Merci
Non pour le Goto tu as raison, il vaut mieux éviter des calculs en trop. Après c'est la commande Goto en elle meme qui est "dépréciée", il vaut mieux faire la meme chose mais avec une autre solution. Utilise peut etre des while, ou alors des If ... Faut adapter. Enfin DKS a ptet une meilleure solution pour remplacer le goto.

Après ce que tu peux faire aussi, c'est rajouter des bouts de codes qui chronometre combien de temps ça prend à s'executer, puis tu essaye de modifier ton codes pour l'améliorer. En cherchant sur le site tu devrais pouvoir trouver des codes de "benchmark" (j'en ai moi meme posté un)

Ciaò
MadMatt
Vb System Library

Merci MadM@tt 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 85 internautes ce mois-ci

Commenter la réponse de MadM@tt
Meilleure réponse
cs_DARKSIDIOUS 15838 Messages postés jeudi 8 août 2002Date d'inscription 4 mars 2013 Dernière intervention - 1 nov. 2006 à 20:15
3
Merci
Non un simple exit sub à la place du goto : ca te quitte ta procédure, et ca t'évite l'utilisation du goto : le goto est à bannir car il rend le code plus difficile à lire, et dans 99% des cas, on peut s'en passer !

Merci cs_DARKSIDIOUS 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 85 internautes ce mois-ci

Commenter la réponse de cs_DARKSIDIOUS
cs_DARKSIDIOUS 15838 Messages postés jeudi 8 août 2002Date d'inscription 4 mars 2013 Dernière intervention - 1 nov. 2006 à 19:52
0
Merci
Bah déjà, 3 boucles for, sans compter le goto qui menne sûrement à une boucle lui aussi, tu as une sacré compléxité là !

Y'a pas de miracles, on peux pas modifier ton algo sans savoir ce qu'il fait ! C'est à toi de modifier ta façon de faire afin de trouver un algo plus performant (si c'est possible !).

Déjà, des toutes petites choses afin d'accélèrer un petit peu (quelques ms, c'est déjà cà...) :

Dim i As Integer
Dim end as Integer
dim end2 as integer
dim work As WorkSheet

end2 = 200 * k - 1
set work = Worksheets("CF_Import_Data")
For k = 1 To 6    
    For j = 200 * (k - 1) To end2
        Line Input #1, Line 
        NumLine = NumLine + 1 
        Varline() = Split(Line, ",")
        end = UBound(Varline)
        For i = 0 To end
            work.Cells((k - 1) * 305 + 1, 1).Offset(i, j - 200 * (k - 1)).Value = Val(Varline(i))
        Next i
        If EOF(1) Then GoTo previous 'a banir le goto !
    Next j
Next k
Commenter la réponse de cs_DARKSIDIOUS
peharant 9 Messages postés mercredi 18 octobre 2006Date d'inscription 4 novembre 2006 Dernière intervention - 1 nov. 2006 à 20:09
0
Merci
en fait le goto mene a la fin de la sub donc ca permet d eviter de faire aller k jusqu a 6... qu est ce qu il vaut mieux en terme de rapidite, enlever le goto et laisser la triple boucle tourner jusqu a la fin ou alors le garder??

Merci
Commenter la réponse de peharant
peharant 9 Messages postés mercredi 18 octobre 2006Date d'inscription 4 novembre 2006 Dernière intervention - 1 nov. 2006 à 20:20
0
Merci
Merci a vous 2 !
Commenter la réponse de peharant
Julien237 884 Messages postés vendredi 3 novembre 2000Date d'inscription 3 mars 2009 Dernière intervention - 1 nov. 2006 à 22:38
0
Merci
Moi je vois autre chose :
Tu as déjà regardé le temps que prenait la fonction Cells ou Range ? C'est litéralement énorme, je ne sais pas ce qu'office nous a fait...

Pout comparaison, le temps d'accès à un tableau dans excel par la méthode Cells est de 30.702237/1000 alors qu'il est de 00.004971/10000 pour un simple tableau de double de la même taille.

Bien entendu je sais que les cellules d'excel sont beaucoup plus complexes... Mais un rapport de 62653, je trouve cela vraiment énorme.
Je te conseil d'enregistrer toutes tes cellules dans un array (Par exemple worksheet.UsedRange.Value te renvoie un array de toutes les valeurs de ta feuille) puis de refaire la fonction offset et de travailler avec cela.

Je travaille moi-même sur un programme devant lire des données d'excel, et j'ai été assez ennuyé en me rendant compte que le temps de lecture de données était beaucoup plus long que le temps de calcul lui-même :p...

Bonne soirée

Julien.
Commenter la réponse de Julien237
BruNews 21054 Messages postés jeudi 23 janvier 2003Date d'inscription 7 novembre 2014 Dernière intervention - 2 nov. 2006 à 01:25
0
Merci
work.Cells((k - 1) * 305 + 1, 1).Offset(i, j - 200 * (k - 1))

il est là le plus gros problème vitesse. Aucun prog ne pourra trouver le pointeur cellule rapidement tant que codé ainsi.

Utilise objet pointeur de cellule.
Exemple:
Sub Testeur()
  Dim cel As Range, cOffst As Range
  Dim L As Long, C As Long
  Dim i As Long, j As Long
  Set cel = Range("A1")
  i = 100   ' ON ECRIT SUR 100 LIGNES
  Do
    cel = L
    Set cOffst = cel.Offset(0, 1) ' DEPART DEPUIS DROITE DE CELLULE COURANTE
    C = L + 1
    j = 20  ' 20 COLONNES ECRITES A DROITE DE LA 1ere
    Do
      cOffst = C
      Set cOffst = cOffst.Offset(0, 1) ' cOffst SE DEPLACE A DROITE
      C = C + 1
      j = j - 1
    Loop While j > 0
    Set cel = cel.Offset(1, 0) ' cel POINTERA 1 LIGNE PLUS BAS
    L = L + 1
    i = i - 1
  Loop While i > 0
End Sub
On écrit ainsi 2100 cellules en ultra rapide car aucun calcul d'indexation.

200 * k - 1
ce calcul ne doit pas être refait (surtout en boucle), place résultat en variable.

Hors cela il n'y a plus rien à optimiser au niveau VB.
Une dll C qui parserait le fichier en te retournant direct les tableaux de valeurs supprimerait cette calamité de Split() et la lecture "par ligne" (TRES LENT) depuis code VB.
Pas le temps de te la faire mais en réunissant morceaux de mes sources, tu devrais y arriver.
Fabrique de tableaux pour VB depuis C est dans ma dernière il me semble.

ciao...
BruNews, MVP VC++
Commenter la réponse de BruNews
XGuarden 259 Messages postés dimanche 14 juillet 2002Date d'inscription 17 août 2012 Dernière intervention - 3 nov. 2006 à 10:18
0
Merci
Je tient ma mette mon petit mot aussi. Bien que la raison réelle de la lenteur soit l'utilisation "mal faite"  du pointeur cellule, voila quelque truc pour augmenter sensiblement la vitesse de ton code:

Premierement je te félicite d'utiliser next j xext i next k , c'Est pluas rapide et plus lisible que juste Next...
Deuxiement For i = 0 To UBound(Varline)
A chaque fois il va recalculer la longueur de varline
utilise plutot
dim BoundVarline=UBound(Varline)
et utilise le BoundVarline à la place, tu va gagner du temps CPU, bien que cela ne sera probablement pas visible.
Tu dois absolument éviter de refaire des caécul déja fait inutilement.
Une erreur que plusieur programmeur vb font est de penser que code plus court égal code plus rapide....
L'utilisation de Val ralenti également la vitesse d'Exécution de ton programme et n'Est en rien necessaire.

Ton goto est également a prescrire, cependant je ne partage pas le point de vue de certain autres à avoir poster un message sur ce poste. Le goto est très bien acceptable au condition suivante: Il augmente la claireté du code ou exprime une idée clair.
Par exemple l'utilisatino de goto comme gestion d'erreur est acceptable si elle est fait systématiquement et corectement.
Finalement je ne suis pas certain de ce point mais je crois qu'il existe une alternative plus rapide a Line Input #1, Line .
Bien entendu les trucs que je viens de mensionner n'augementeron pas la vitesse de ton code suffisament pour que tu puise t'en rendre compte. La facons la plus efficace est d'attaquer ta ligne Worksheets("CF... . à elle tout seule je suis certain qu'elle prend 100 fois plus de temps a s'executer que tout le reste réunis. Essaye de modifier ton code pour ajouter une ligne tout dun coup.
Commenter la réponse de XGuarden
peharant 9 Messages postés mercredi 18 octobre 2006Date d'inscription 4 novembre 2006 Dernière intervention - 3 nov. 2006 à 16:29
0
Merci
merci a tous!
Commenter la réponse de peharant

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.