Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

FOR contre DO. Le retour de la revanche...

2 réponses
Avatar
jmn
J'ai trouvé très distrayante la discussion du 24 à propos des mérites
comparés de FOR...NEXT et DO... Il m'a semblé utile de fournir un éclairage
un peu différent au débat :


1° LA REALITE BRUTE
---------------------

Juste en dessous, un code en langage 'évolué' VB, puis sa transcription en
langage machine (présentée sous forme assemblée).


LE PROGRAMME EN VB

Sub Main()
Dim i%, j%, k%
Dim a%
Beep ' juste pour retoruver plus facilement le bout de code dans l'exe.
'
' l'instruction a=a+1 n'est là que pour marquer la place du corps de boucle
'
' for next sur constantes
a = 0
For i = 0 To 10
a = a + 1
Next
' do while sur constante
i = 0
Do While i <= 10
i = i + 1
a = a + 1
Loop
' for next sur variables
j = 0
k = 10
For i = j To k
a = a + 1
Next
' do while sur variable
i = 0
k = 10
Do While i <= k
i = i + 1
a = a + 1
Loop
End Sub


LA PORTION CORRESPONDANTE DE L'EXECUTABLE (compilation VB6 SP5) :

00401560 call dword ptr ds:[40103Ch] ' beep
00401566 xor eax,eax ' raz i
00401568 xor ecx,ecx ' raz a
0040156A add ax,1 ' a=a+1 (le for...
next rebranche ici) --------------+
0040156E jo 004015B9 ' test de dépacement
de capacité !
00401570 add cx,1 ' i=i+1
!
00401574 jo 004015B9 '
!
00401576 cmp cx,0Ah ' i ? 10
!
0040157A jle 0040156A ' si <= on
recommence ---------------------------+
0040157C xor ecx,ecx ' raz i
0040157E add cx,1 ' i=i+1 (le do...
while rebranche ici)-----------------+
00401582 jo 004015B9 '
!
00401584 add ax,1 ' a=a+1
!
00401588 jo 004015B9 '
!
0040158A cmp cx,0Ah ' i ? 10
!
0040158E jle 0040157E ' si <= on
recommence -----------------------------+
00401590 xor ecx,ecx ' raz i
00401592 add ax,1 ' a=a+1 (le
for... next rebranche ici)-----------------+
00401596 jo 004015B9 '
!
00401598 add cx,1 ' i=i+1
!
0040159C jo 004015B9 '
!
0040159E cmp cx,0Ah ' i ? 10 (!)
!
004015A2 jle 00401592 ' si <= on
recommence ----------------------------+
004015A4 xor ecx,ecx ' raz i
004015A6 add cx,1 ' a=a+1 (le do...
while rebranche ici)--------------------+
004015AA jo 004015B9 '
!
004015AC add ax,1 ' i=i+1
!
004015B0 jo 004015B9 '
!
004015B2 cmp cx,0Ah ' i ? 10 (!)
!
004015B6 jle 004015A6 ' si <= on
recommence ---------------------------------+
004015B8 ret ' retour
004015B9 call dword ptr ds:[401044h] ' branchement en cas
d'erreur



d'où l'observateur attentif pourra tirer 3 conclusions immédiates :

- comme on pouvez s'y attendre, les FOR et les DO sont compilés exactement
de la même manière (FOR étant un cas particulier de DO),

- le compilateur (parce que dans ce cas cela est possible) utilise au
maximum les registres pour limiter (dans notre cas pour supprimer) les
échanges mémoire/registre pendant le traitement.

- le compilateur est suffisement intelligent pour s'apercevoir que les
variables chargées avec 10 dans le code VB servent uniquement de borne et il
les remplace par une constante !

On notera qu'avec un petit effort, le programmeur de Microsoft aurait pu
tester le cas, très fréquent, de l'incrément par 1 et générer des INC CX à
la place des ADD CX,1 ce qui aurait pour effet de gagner 1 cycle à chaque
fois... Ce qui procurerait un gain mesurable après quelques millions
d'instructions !



2° LE COMMENTAIRE

Les langages évolués, comme VB, Pascal, C, COBOL, FORTRAN et tous les
autres, ont pour finalité de fournir au développeur un mode d'expression qui
soit plus proche de 'la chose à modéliser' que du fonctionnement de
l'ordinateur. La traduction, si possible la plus efficace possible, du
programme 'langage évolué' en langage machine est le travail du compilateur.

On peut discuter de l'aspect esthétique et des mérites comparés de la boucle
FOR NEXT et des boucles DO... (historiquement les boucles FOR viennent de
FORTRAN puis des premiers BASIC, donc des applications scientifiques des
années 50/60, et les structures DO... viennent d'ALGOL et Pascal, donc des
travaux mathématiques sur les transcriptions d'algorithmes des années 70).
Cette discussion relève de la méthodologie de programmation. Mais pour
connaitre l'efficacité brute de l'exécutable généré VB n'offre pas d'autre
choix que de faire des essais !

En effet, l'exemple précédent n'est qu'un cas particulier. D'autres codes
différents ou plus complexes vont être traduit de manière différente par le
compilateur (surtout lorsque le nombre de variables mises en oeuvre dans une
procédure ne va plus permettre de travailler directement sur les registres
de bout en bout).

A ce propos, il est dommage que Microsoft ne fournisse pas (du moins pas à
ma connaissance) de description précise des stratégies mises en oeuvre par
ses compilateurs en fonction du code en langage évolué (ce qui était le cas
il y a bien longtemps sur les grand systèmes et les minis). Cela permettrait
aux programmeurs attachés à un gain de quelques milli secondes de choisir
leur mode de programmation en toute connaissance de cause.


Bonne journée
JMN

2 réponses

Avatar
Patrice Henrio
Très instructif et commentaires intéressants. Finalement un forum c'est bien
aussi pour échanger sur la programmation et pas seulement pour obtenir de
l'aide.

"jmn" a écrit dans le message de
news:%23kaMsHE$
J'ai trouvé très distrayante la discussion du 24 à propos des mérites
comparés de FOR...NEXT et DO... Il m'a semblé utile de fournir un


éclairage
un peu différent au débat :


1° LA REALITE BRUTE
---------------------

Juste en dessous, un code en langage 'évolué' VB, puis sa transcription en
langage machine (présentée sous forme assemblée).


LE PROGRAMME EN VB

Sub Main()
Dim i%, j%, k%
Dim a%
Beep ' juste pour retoruver plus facilement le bout de code dans l'exe.
'
' l'instruction a=a+1 n'est là que pour marquer la place du corps de


boucle
'
' for next sur constantes
a = 0
For i = 0 To 10
a = a + 1
Next
' do while sur constante
i = 0
Do While i <= 10
i = i + 1
a = a + 1
Loop
' for next sur variables
j = 0
k = 10
For i = j To k
a = a + 1
Next
' do while sur variable
i = 0
k = 10
Do While i <= k
i = i + 1
a = a + 1
Loop
End Sub


LA PORTION CORRESPONDANTE DE L'EXECUTABLE (compilation VB6 SP5) :

00401560 call dword ptr ds:[40103Ch] ' beep
00401566 xor eax,eax ' raz i
00401568 xor ecx,ecx ' raz a
0040156A add ax,1 ' a=a+1 (le


for...
next rebranche ici) --------------+
0040156E jo 004015B9 ' test de dépacement
de capacité !
00401570 add cx,1 ' i=i+1
!
00401574 jo 004015B9 '
!
00401576 cmp cx,0Ah ' i ? 10
!
0040157A jle 0040156A ' si <= on
recommence ---------------------------+
0040157C xor ecx,ecx ' raz i
0040157E add cx,1 ' i=i+1 (le


do...
while rebranche ici)-----------------+
00401582 jo 004015B9 '
!
00401584 add ax,1 ' a=a+1
!
00401588 jo 004015B9 '
!
0040158A cmp cx,0Ah ' i ? 10
!
0040158E jle 0040157E ' si <= on
recommence -----------------------------+
00401590 xor ecx,ecx ' raz i
00401592 add ax,1 ' a=a+1 (le
for... next rebranche ici)-----------------+
00401596 jo 004015B9 '
!
00401598 add cx,1 ' i=i+1
!
0040159C jo 004015B9 '
!
0040159E cmp cx,0Ah ' i ? 10 (!)
!
004015A2 jle 00401592 ' si <= on
recommence ----------------------------+
004015A4 xor ecx,ecx ' raz i
004015A6 add cx,1 ' a=a+1 (le


do...
while rebranche ici)--------------------+
004015AA jo 004015B9 '
!
004015AC add ax,1 ' i=i+1
!
004015B0 jo 004015B9 '
!
004015B2 cmp cx,0Ah ' i ? 10 (!)
!
004015B6 jle 004015A6 ' si <= on
recommence ---------------------------------+
004015B8 ret ' retour
004015B9 call dword ptr ds:[401044h] ' branchement en cas
d'erreur



d'où l'observateur attentif pourra tirer 3 conclusions immédiates :

- comme on pouvez s'y attendre, les FOR et les DO sont compilés exactement
de la même manière (FOR étant un cas particulier de DO),

- le compilateur (parce que dans ce cas cela est possible) utilise au
maximum les registres pour limiter (dans notre cas pour supprimer) les
échanges mémoire/registre pendant le traitement.

- le compilateur est suffisement intelligent pour s'apercevoir que les
variables chargées avec 10 dans le code VB servent uniquement de borne et


il
les remplace par une constante !

On notera qu'avec un petit effort, le programmeur de Microsoft aurait pu
tester le cas, très fréquent, de l'incrément par 1 et générer des INC CX à
la place des ADD CX,1 ce qui aurait pour effet de gagner 1 cycle à chaque
fois... Ce qui procurerait un gain mesurable après quelques millions
d'instructions !



2° LE COMMENTAIRE

Les langages évolués, comme VB, Pascal, C, COBOL, FORTRAN et tous les
autres, ont pour finalité de fournir au développeur un mode d'expression


qui
soit plus proche de 'la chose à modéliser' que du fonctionnement de
l'ordinateur. La traduction, si possible la plus efficace possible, du
programme 'langage évolué' en langage machine est le travail du


compilateur.

On peut discuter de l'aspect esthétique et des mérites comparés de la


boucle
FOR NEXT et des boucles DO... (historiquement les boucles FOR viennent de
FORTRAN puis des premiers BASIC, donc des applications scientifiques des
années 50/60, et les structures DO... viennent d'ALGOL et Pascal, donc des
travaux mathématiques sur les transcriptions d'algorithmes des années 70).
Cette discussion relève de la méthodologie de programmation. Mais pour
connaitre l'efficacité brute de l'exécutable généré VB n'offre pas d'autre
choix que de faire des essais !

En effet, l'exemple précédent n'est qu'un cas particulier. D'autres codes
différents ou plus complexes vont être traduit de manière différente par


le
compilateur (surtout lorsque le nombre de variables mises en oeuvre dans


une
procédure ne va plus permettre de travailler directement sur les registres
de bout en bout).

A ce propos, il est dommage que Microsoft ne fournisse pas (du moins pas à
ma connaissance) de description précise des stratégies mises en oeuvre par
ses compilateurs en fonction du code en langage évolué (ce qui était le


cas
il y a bien longtemps sur les grand systèmes et les minis). Cela


permettrait
aux programmeurs attachés à un gain de quelques milli secondes de choisir
leur mode de programmation en toute connaissance de cause.


Bonne journée
JMN











Avatar
ng
Très interressant ;-)

--
Nicolas G.
FAQ VB : http://faq.vb.free.fr
API Guide : http://www.allapi.net
Google Groups : http://groups.google.fr/
MZ-Tools : http://www.mztools.com/
"jmn" a écrit dans le message de news:
#kaMsHE$
J'ai trouvé très distrayante la discussion du 24 à propos des mérites
comparés de FOR...NEXT et DO... Il m'a semblé utile de fournir un


éclairage
un peu différent au débat :


1° LA REALITE BRUTE
---------------------

Juste en dessous, un code en langage 'évolué' VB, puis sa transcription en
langage machine (présentée sous forme assemblée).


LE PROGRAMME EN VB

Sub Main()
Dim i%, j%, k%
Dim a%
Beep ' juste pour retoruver plus facilement le bout de code dans l'exe.
'
' l'instruction a=a+1 n'est là que pour marquer la place du corps de


boucle
'
' for next sur constantes
a = 0
For i = 0 To 10
a = a + 1
Next
' do while sur constante
i = 0
Do While i <= 10
i = i + 1
a = a + 1
Loop
' for next sur variables
j = 0
k = 10
For i = j To k
a = a + 1
Next
' do while sur variable
i = 0
k = 10
Do While i <= k
i = i + 1
a = a + 1
Loop
End Sub


LA PORTION CORRESPONDANTE DE L'EXECUTABLE (compilation VB6 SP5) :

00401560 call dword ptr ds:[40103Ch] ' beep
00401566 xor eax,eax ' raz i
00401568 xor ecx,ecx ' raz a
0040156A add ax,1 ' a=a+1 (le


for...
next rebranche ici) --------------+
0040156E jo 004015B9 ' test de dépacement
de capacité !
00401570 add cx,1 ' i=i+1
!
00401574 jo 004015B9 '
!
00401576 cmp cx,0Ah ' i ? 10
!
0040157A jle 0040156A ' si <= on
recommence ---------------------------+
0040157C xor ecx,ecx ' raz i
0040157E add cx,1 ' i=i+1 (le


do...
while rebranche ici)-----------------+
00401582 jo 004015B9 '
!
00401584 add ax,1 ' a=a+1
!
00401588 jo 004015B9 '
!
0040158A cmp cx,0Ah ' i ? 10
!
0040158E jle 0040157E ' si <= on
recommence -----------------------------+
00401590 xor ecx,ecx ' raz i
00401592 add ax,1 ' a=a+1 (le
for... next rebranche ici)-----------------+
00401596 jo 004015B9 '
!
00401598 add cx,1 ' i=i+1
!
0040159C jo 004015B9 '
!
0040159E cmp cx,0Ah ' i ? 10 (!)
!
004015A2 jle 00401592 ' si <= on
recommence ----------------------------+
004015A4 xor ecx,ecx ' raz i
004015A6 add cx,1 ' a=a+1 (le


do...
while rebranche ici)--------------------+
004015AA jo 004015B9 '
!
004015AC add ax,1 ' i=i+1
!
004015B0 jo 004015B9 '
!
004015B2 cmp cx,0Ah ' i ? 10 (!)
!
004015B6 jle 004015A6 ' si <= on
recommence ---------------------------------+
004015B8 ret ' retour
004015B9 call dword ptr ds:[401044h] ' branchement en cas
d'erreur



d'où l'observateur attentif pourra tirer 3 conclusions immédiates :

- comme on pouvez s'y attendre, les FOR et les DO sont compilés exactement
de la même manière (FOR étant un cas particulier de DO),

- le compilateur (parce que dans ce cas cela est possible) utilise au
maximum les registres pour limiter (dans notre cas pour supprimer) les
échanges mémoire/registre pendant le traitement.

- le compilateur est suffisement intelligent pour s'apercevoir que les
variables chargées avec 10 dans le code VB servent uniquement de borne et


il
les remplace par une constante !

On notera qu'avec un petit effort, le programmeur de Microsoft aurait pu
tester le cas, très fréquent, de l'incrément par 1 et générer des INC CX à
la place des ADD CX,1 ce qui aurait pour effet de gagner 1 cycle à chaque
fois... Ce qui procurerait un gain mesurable après quelques millions
d'instructions !



2° LE COMMENTAIRE

Les langages évolués, comme VB, Pascal, C, COBOL, FORTRAN et tous les
autres, ont pour finalité de fournir au développeur un mode d'expression


qui
soit plus proche de 'la chose à modéliser' que du fonctionnement de
l'ordinateur. La traduction, si possible la plus efficace possible, du
programme 'langage évolué' en langage machine est le travail du


compilateur.

On peut discuter de l'aspect esthétique et des mérites comparés de la


boucle
FOR NEXT et des boucles DO... (historiquement les boucles FOR viennent de
FORTRAN puis des premiers BASIC, donc des applications scientifiques des
années 50/60, et les structures DO... viennent d'ALGOL et Pascal, donc des
travaux mathématiques sur les transcriptions d'algorithmes des années 70).
Cette discussion relève de la méthodologie de programmation. Mais pour
connaitre l'efficacité brute de l'exécutable généré VB n'offre pas d'autre
choix que de faire des essais !

En effet, l'exemple précédent n'est qu'un cas particulier. D'autres codes
différents ou plus complexes vont être traduit de manière différente par


le
compilateur (surtout lorsque le nombre de variables mises en oeuvre dans


une
procédure ne va plus permettre de travailler directement sur les registres
de bout en bout).

A ce propos, il est dommage que Microsoft ne fournisse pas (du moins pas à
ma connaissance) de description précise des stratégies mises en oeuvre par
ses compilateurs en fonction du code en langage évolué (ce qui était le


cas
il y a bien longtemps sur les grand systèmes et les minis). Cela


permettrait
aux programmeurs attachés à un gain de quelques milli secondes de choisir
leur mode de programmation en toute connaissance de cause.


Bonne journée
JMN