Page 1 sur 1
Remplir un tableau
Publié : sam. 19/nov./2005 10:38
par Dräc
Voici deux codes pour remplir un tableau à deux dimensions.
Le premier est classique (deux boucles imbriquées), le deuxième utilise un pointeur.
Je suis surpris de constater que le deuxième prend plus de temps que le premier!
Pourtant, le nombre d’opérations dans la boucle est moindre.
En effet, dans le programme n°1, l’adresse mémoire est recalculée à chaque itération en fonction de la valeur de i et j,
alors que dans le deuxième, on ne fait qu’incrémenter un pointeur… sans compter qu’il n’y a qu’une seule boucle…
Quelqu’un a t’il une explication ?
#size = 1000
Dim table.l( #size , #size )
Time = GetTickCount_()
For i=0 To #size
For j = 0 To #size
table(i,j)=1000;Random(300)
Next
Next
Debug GetTickCount_()-Time
Time = GetTickCount_()
*pt.LONG = @table()
For k=1 To ( #size+1 )*( #size+1 )
*pt\l = 2000;Random(300)
*pt + SizeOf(LONG)
Next
Debug GetTickCount_()-Time
Publié : sam. 19/nov./2005 11:36
par Gillou
Tu devrais essayer ça
#size = 1000
Dim table.l( #size , #size )
Time = GetTickCount_ ()
For i=0 To #size
For j = 0 To #size
table(i,j)=1000
Next
Next
Debug GetTickCount_ ()-Time
Time = GetTickCount_ ()
*pt.LONG = @table()
t=( #size +1 )*( #size +1 )+*pt
For *pt=*pt To t Step 4
*pt\l = 100
Next
Debug GetTickCount_ ()-Time
Publié : sam. 19/nov./2005 11:46
par Dräc
Il faudrait d'abord que tu remplisses effectivement tout le tableau pour bien comparer
#size = 1000
Dim table.l( #size , #size )
Time = GetTickCount_ ()
For i=0 To #size
For j = 0 To #size
table(i,j)=1000
Next
Next
Debug GetTickCount_ ()-Time
Time = GetTickCount_ ()
*pt.LONG = @table()
t=( #size +1 )*( #size +1 )*4+*pt
For *pt=*pt To t Step 4
*pt\l = 2000
Next
Debug GetTickCount_ ()-Time
Mais cela n'est qu'une optimisation de plus et n'explique pas ma premiere constatation...
Publié : sam. 19/nov./2005 11:56
par Gillou
C'est vrai, Oups

, pour comparer en un peu plus prècis
Pour l'explication? je cherche
#size = 1000
Dim table.l( #size , #size )
For a=1 To 10
Time = GetTickCount_ ()
For i=0 To #size
For j = 0 To #size
table(i,j)=1000
Next
Next
time2= GetTickCount_ ()-Time+time2
Next
Debug time2/10
time2=0
For a=1 To 10
Time = GetTickCount_ ()
*pt.LONG = @table()
t=( #size +1 )*( #size +1 )*4+*pt
For *pt=*pt To t Step 4
*pt\l = 100
Next
time2= GetTickCount_ ()-Time+time2
Next
Debug time2/10
Publié : sam. 19/nov./2005 12:16
par Dräc
Ainsi simplifié, ca me parait plus clair :
#size = 1000
Dim table.l( #size , #size )
Time = GetTickCount_ ()
For a=1 To 10
For i=0 To #size
For j = 0 To #size
table(i,j)=1000
Next
Next
Next
Debug ( GetTickCount_ ()-Time)/10
Time = GetTickCount_ ()
For a=1 To 10
*pt.LONG = @table()
t=( #size +1 )*( #size +1 )*4+*pt
For *pt=*pt To t Step 4
*pt\l = 100
Next
Next
Debug ( GetTickCount_ ()-Time)/10
Publié : sam. 19/nov./2005 12:30
par Gillou
Tu obtiens quoi comme temps ?
Méthode 1 : 128 ms
Méthode 2 : 115 ms
Mais, c'est pas très significatif tout ça

Publié : sam. 19/nov./2005 12:45
par Dräc
Toutes proportions gardées (P3 500Mhz), j’obtiens :
Méthode n°1 : 583
Méthode n°2 : 542
Ce qui n’est pas vraiment significatif comme tu le souligne, malgré l’impression d’avoir simplifié: d’où mon interrogation !
Publié : sam. 19/nov./2005 13:16
par Gillou
Publié : sam. 19/nov./2005 13:34
par Dräc
En fait je me base sur le code assembler pour essayer de comprendre.
Ce que j’y vois, c’est que la méthode 2 est tout de meme plus simple.
Méthode n°1
; For i=0 To #size
MOV dword [v_i],0
_For3:
MOV eax,1000
CMP eax,dword [v_i]
JL _Next4
; For j = 0 To #size
MOV dword [v_j],0
_For5:
MOV eax,1000
CMP eax,dword [v_j]
JL _Next6
; table(i,j)=1000
MOV edx,[a_table+4]
IMUL edx,dword [v_i]
MOV ebp,edx
PUSH ebp
MOV eax,dword [v_j]
POP ebp
ADD ebp,eax
SAL ebp,2
ADD ebp,dword [a_table]
MOV dword [ebp],1000
; Next
_NextContinue6:
INC dword [v_j]
JMP _For5
_Next6:
; Next
_NextContinue4:
INC dword [v_i]
JMP _For3
_Next4:
Méthode n°2
; *pt.LONG = @table()
PUSH dword [a_table]
POP dword [p_pt]
; t=( #size +1 )*( #size +1 )*4+*pt
MOV ebx,dword [p_pt]
ADD ebx,4008004
MOV dword [v_t],ebx
; For *pt=*pt To t Step 4
PUSH dword [p_pt]
POP dword [p_pt]
_For9:
MOV eax,dword [v_t]
CMP eax,dword [p_pt]
JL _Next10
; *pt\l = 100
MOV ebp,dword [p_pt]
MOV dword [ebp],100
; Next
_NextContinue10:
ADD dword [p_pt],4
JMP _For9
_Next10:
Publié : dim. 20/nov./2005 6:17
par filperj
En désactivant le débogueur, l'écart est déjà plus net!
Et c'est bien Monsieur Pointeur qui gagne, même avec la 1ère méthode.