Remplir un tableau

Sujets variés concernant le développement en PureBasic
Dräc
Messages : 526
Inscription : dim. 29/août/2004 0:45

Remplir un tableau

Message 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
Gillou
Messages : 373
Inscription : sam. 28/août/2004 17:35
Localisation : Bretagne, 22
Contact :

Message par Gillou »

Tu devrais essayer ça :wink:


#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
Dräc
Messages : 526
Inscription : dim. 29/août/2004 0:45

Message 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...
Gillou
Messages : 373
Inscription : sam. 28/août/2004 17:35
Localisation : Bretagne, 22
Contact :

Message par Gillou »

C'est vrai, Oups :oops: , 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
Dräc
Messages : 526
Inscription : dim. 29/août/2004 0:45

Message 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
Gillou
Messages : 373
Inscription : sam. 28/août/2004 17:35
Localisation : Bretagne, 22
Contact :

Message 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 :)
Dräc
Messages : 526
Inscription : dim. 29/août/2004 0:45

Message 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 !
Gillou
Messages : 373
Inscription : sam. 28/août/2004 17:35
Localisation : Bretagne, 22
Contact :

Message par Gillou »

Avec une moyenne harmonique l'écart est encore moins significatif :(

Peut-être une réponse, la fonction tableau de purebasic est super optimisé :D :D :D
Dräc
Messages : 526
Inscription : dim. 29/août/2004 0:45

Message 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:
filperj
Messages : 395
Inscription : jeu. 22/janv./2004 1:13

Message 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.
Le chaos l'emporte toujours sur l'ordre
parcequ'il est mieux organisé.
(Ly Tin Wheedle)
Répondre