Vitesse d'exécution des procédure VBA en fonction de la structure du code

Bonjour,

au vu du fichier joint, la structure qui parait la plus rapide (sauf erreur de ma part au niveau du code) c'es la structure "unique" :
un seul module avec une seule procédure ou SUB.

Les 4 autres propositions sont :
- une Sub qui lance les 5 Sub les unes après les autres mais elles sont toutes dans le même module
- une Sub qui lance les 5 Sub les unes après les autres mais chacune se trouve dans un module différent
- une Sub qui lance une autre Sub qui lance la Sub suivante, elles sont en cascades mais toutes dans le même module
- Une Sub qui lance une autre Sub qui lance la Sub suivante, elles sont en cascades mais chacune dans un module différent

La première suivant les test est de 3 à 5 fois plus rapide que les 4 autres.

Alors si je prends en exemple mon application ArkaLouReeD Light ! j'ai fait une Sub principale pour la boucle de jeu et dans cette dernière je fais appel aux différentes Sub nécessaires pour les différentes actions à faire sur le jeu. Si j'en crois mes tests, il faudrait que je regroupe toutes ces Sub au sein de la principale afin d'aller de 3 à 5 fois plus vite !

Alors oui je gagnerais en théorie en vitesse mais je perdrais en simplicité de lecture du code et pour "l'entretien" et la modification de ce dernier cela compliquerait l'affaire, non ?

En testant juste la promenade du code, en retirant l'incrément des 5 variables, les codes en cascades sont légèrement plus rapide que les deux autres, l'unique reste le plus rapide.

J'ai fait des tests en typant les variables, les 5 codes sont plus rapides, mais "l'unique" reste devant.

Qu'en pensez vous ?

Le fichier :

@ bientôt

LouReeD

Bonjour LouReeD,

L'appel d'une SUB ou d'une fonction engendre nécessairement l'exécution d'instructions supplémentaire (initialisation de la sub, de ses variables, ...) qui deviennent très visibles dès lors qu'on les appelle des milliers de fois comme dans ton test.

tu peux également garder une certaine structure avec la combinaison gosub, return qui consomme moins d'instructions et donc plus rapide.

Sub Uniquegosub()
      Tempo = Timer
      For J = 1 To 10
          For i = 1 To 1000000
              GoSub 1
              GoSub 2
              GoSub 3
              GoSub 4
              GoSub 5
          Next i
      Next J
      Range("F2") = Timer - Tempo & " secondes"
      Exit Sub
1:    A = A + 1: Return
2:    b = b + 1: Return
3:    c = c + 1: Return
4:    d = d + 1: Return
5:    e = e + 1: Return
End Sub

Bonjour,

Merci pour cette information !

Il est vrai qu'il y une demande d'1000000 d'accès, c'est peu probable, mais cela a le mérite de démontrer la chose, tout comme le fait de l'accélération du code avec des variables public donc créer une seule fois, même avec la sub unique, on passe de 0,07 à 0,02 de mémoire !

@ bientôt

LouReeD

Bonjour acide !

si je vous comprend bien je peux faire un code de ce type :

Sub LRD()
    Do
        If Monstres Then Goto 1
        If Mur Then Goto 2
    Loop While Joue=True
Exit sub
'**********************************************************
1:
    For I=1 To 3
        If Monstre(I).Visible Then Goto DeplacementMonstre
    Next I
Return
'**********************************************************
2:
    Mur.Height = Mur.Height +1
Return
'**********************************************************
DeplacementMonstre :
    Monstre(I).Top = 25
    Monstre(I).Left = 152
Return
'**********************************************************
End Sub

@ bientôt

LouReeD

Bonjour LouReed,

Le return fonctionne avec Go sub et non goto. Pour faire l’équivalent avec goto il faut remplacer l’instruction return par un goto en mentionnant le point de retour.

Faute de frappe de ma part !

Sub LRD()
    Do
        If Monstres Then GoSub 1
        If Mur Then GoSub 2
    Loop While Joue=True
Exit sub
'**********************************************************
1:
    For I=1 To 3
        If Monstre(I).Visible Then GoSub DeplacementMonstre
    Next I
Return
'**********************************************************
2:
    Mur.Height = Mur.Height +1
Return
'**********************************************************
DeplacementMonstre :
    Monstre(I).Top = 25
    Monstre(I).Left = 152
Return
'**********************************************************
End Sub

Donc une structure comme celle-ci fonctionnerait, on remplace les "Sub" par des "étiquettes" et les "End Sub" par des "Return".

@ bientôt

LouReeD

Bonjour à tous,

Tu touches un point qui m'attriste mais c'est bien le cas.

En fait VBA est un langage "interprété" (en opposition aux langages "compilés"). C'est à dire qu'il est exécuté ligne par ligne un peu "sans savoir ce qu'il y a après".

Comme déjà dit par h2so4 le problème de ce fonctionnement est que le programme ne garde pas en mémoire les autres Sub/Fonctions, il charge le sub initial, et tant que tu n'as pas appelé un autre sub, ce dernier n'est pas évalué. Et donc quand on l'appelle, VBA le lit/charge/exécute, puis revient au programme initial et "oublie". D'où le problème du temps d'exécution à rallonge quand tu as des milliers d'appels.

Je m'en suis rendu compte par exemple sur certaines fonctions que j'ai pu coder (des histoires de permutations notamment) et @BsAlv également. Même si la complexité théorique de mes programmes était inférieure (moins de boucles donc devrait être plus rapide), la structure de mon code + complexe (subs/fonctions/classes vs "gros bloc") me faisait atteindre des temps d'exécution + longs. Les structures complexes ne posent aucun problème en "compilé" : là où j'ai appris à programmer, car le programme se charge "en entier" avant l'exécution. L'avantage c'est que ça rend le code beaucoup plus lisible/compréhensible et adaptable.

A toi de voir à quel point ces performances sont impactantes pour toi, une solution pourrait être de coder en "blocs" puis lorsque c'est fonctionnel "regrouper" dans un sub unique en c/c le code de la fonction là où elle est appelée… (mais l'horreur à relire + attention aux doubles déclarations de variables.). Les goto sont probablement mieux.

bonjour,

j'ai l'intention d'essayer, mais comme pour ArkaLouReeD cela va être compliqué.

Sinon le GoSub me plait bien dans le sens qu'il reprend l'idée du Sub et EndSub, enfin si j'ai bien compris. Le Goto on doit lui mettre un nouveau Goto pour revenir où l'on était, non ? Cela augmente encore le nombre d'étiquettes me semble t il, non ?

@ bientôt

LouReeD

Oui pardon j'ai écrit goto mais je voulais dire gosub. Il n'y a pas de return pour les goto apparemment.

Rechercher des sujets similaires à "vitesse execution procedure vba fonction structure code"