Oui en effet je pensais pas que faire:
ind3 = t_part[i]->nvar_mone ;
ca prendrais moins de temps que de mettre directement t_part[i]->nvar_mone .
Pour memmove, je suppose qu'on gagne du temps ...
En tout cas merci pr tous ces conseils![]()
Oui en effet je pensais pas que faire:
ind3 = t_part[i]->nvar_mone ;
ca prendrais moins de temps que de mettre directement t_part[i]->nvar_mone .
Pour memmove, je suppose qu'on gagne du temps ...
En tout cas merci pr tous ces conseils![]()
Pour tes deux derniers exemples, on gagnerai vraiment?
Parce que finalement si non prends ton premer exemple, on boucle toujours sur k, et on doit en plus incrémenter x0 , donc on ajoute quelques opérations non?
pour memmove tu gagnes énormémentEnvoyé par vinzzzz
Et pour le reste, tu gagnes peu, mais sur beaucoup tu gagnes beaucoup : à chaque fois, tu fais une somme (pour calculer l'adresse) au lieu d'avoir le chiffre déjà prêt...
Et c'est vrai pour chaque indice. Et pour l'élément du tableau :
Vaux mieux mettre :
tab[i] que tab[fonction(i)]
valtab que tab[i]
donc si tu fais référence à plusieurs fois le même élément tu le mets dans une variable, si tu fais référence à plusieurs fois le même indice tu le mets dans une variable intermédiaire..
nonEnvoyé par vinzzzz
Quand tu fais :
il faut calculer :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 for(k = t_part[i]->delay_pone ; k > 0 ; k--) { t_part[i]->x[j][k] = t_part[i]->x[j][k-1] ;
l'adresse t->part[i] : 1 somme (éventuellement *2 si pas flag optimisé)
l'adresse t->part[i]->x : 1 somme ( kif kif)
l'adresse t->part[i]->x[j] : 1 somme (kif kif)
l'adresse t->part[i]->x[j][k] : 1 somme
l'adresse t->part[i]->x[j][k-1] : 1 somme
donc entre 5 et 8 sommes
Alors que dans :
calculer x0 -1 : une somme
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 for(k = t_part[i]->delay_pone ; k > 0 ; k--) { *x0 = *(x0-1) ; x0= x0 - 1 ;
l'affecter : une copie ou une somme (dépendant de comment c'est optimisé)
Donc en net 2 sommes max.
Il n'y a que là ou je ne suis pas sûr si on gagnerais en faisant :
p = x0 -1
*x0 = *p
x0 = p ;
mais sans doute (la copie doit prendre moins de temps que la somme)
et dans ce cas on aurait (une somme + 2 copies)
Tu as des exemples concrets... (parce que je vois pas à quel niveau il pourrait y avoir une quelconque différence)Envoyé par lun4t1k
Thierry
"The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
"If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow
FAQ-Python FAQ-C FAQ-C++
+
Si j'ai bien compris, quand je fais:
Cette instruction:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 for(j = 0 ; j < t_part[i]->nvar ; j++) { for(k = t_part[i]->delay_pone ; k > 0 ; k--) { t_part[i]->x[j][k] = t_part[i]->x[j][k-1] ; } }
t_part[i]->x[j][k]
va demander en fait a chaque fois un calcul pour obtenir t_part[i]->x[j], alors que j'aurais pu l'obtenir en une fois juste avant de rentrer dans la deuxième boucle?
Et de la même manière, puisque j'utilise beaucoup le pointeur qui se trouve a t_part[i], si je stocke t_part[i] dans une variable intemédiaire au tout début de la boucle principale, ca éviterait également des calculs pour le récupérer dans le tableau?
Hésite pas a me coriger si jsuis a coté de la plaque![]()
Ok donc y'a encore vraiment moyen d'améliorer tout ca... Merci pour toutes ces précisions.
C'est pour ça que je me permettais de douter en te lisant...
Envoyé par vinzzzz
![]()
L'ignorant qui s'ignore![]()
Mais ca fait d'autant plus plaisir d'en apprendre encore!
En fait tous ces calculs d'adresse avec les tableau, les pointeurs etc... intuitivement j'y ait pas pensé. Et ca explique je suppose pourquoi le parcours d'une liste chainée ca prends plus de temps que celui d'un tableau.
Absolument.... C'est le principe..Envoyé par vinzzzz
Après, comme on disait plus haut, il y a d'autres choses, les structures, les avantages du langage (comme le memmove) etc... mais là déjà, sans remettre en cause la structure du programme , déjà c'est nettement plus lisible, et ensuite on a optimisé le code "hors structure"..
Malheureusement , ce jour là je n'ai pas noté cet algorithme.Envoyé par mujigka
La seule chose que j'ai c'est que ca vient d'un prof d'algo.![]()
La complexité de la boucle for est calculée par la complexité du corps de cette boucle multipliée par le nombre de fois qu’elle est répétée.
En règle générale, pour déterminer la complexité d’une boucle while, il faut avant tout déterminer le nombre de fois que cette boucle est répétée, ensuite le multiplier par la complexité du corps de cette boucle.
Il est parfois plus difficile de compter le nombre de répétitions
Mais d'accord qu'on analyse les boucles while comme les boucles for.
nombre de répétitions du while? pas évident sans calcul.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 int PGCD(int A, int B){ int reste; reste = A % B; while (reste !== 0) { A = B; B = reste; reste = A % B; } return(B);
le for est plus "simple", c'est peut etre un abus de langage la facon dont j'utilise le mot simple.
Cependant j'espère m'être fait comprendre!
for(;condest strictement equivalent a while(cond). Donc il doit y avoir les memes problemes en calcul de complexite. Ton prof parlait peut-etre d'une forme restreinte de for.
Quant au while() (et donc le for de C), il permet l'ecriture de boucles dont on ne sait meme pas si elles se terminent ou pas. Alors evaluer le nombre de passages...
J'ai pas regardé d'exemple avec un compilateur récent, mais dans celui que je connais (datant de 1998), les switchs sont compilés de 2 façons différentes :Envoyé par souviron34
- une suite de tests/goto (éventuellement des tests malins, du genre décrémenter la valeur et sauter si résultat nul, du genre DEC ECX / JEQ xxx / SUB ECX, 2 / JEQ yyy / ...)
- une table de pointeurs, et utilisation de la valeur testée comme index dans cette table
D'ailleurs en ASM, je ne voit pas comment on peut autrement. Donc si tes valeurs possibles (les différents case) ne sont pas assez regroupés, ton switch sera converti en une suite de if/else.
Je ne parle pas de boucles infinies! celles ci mises a part, pour un algo qui termine, avec une complexité calculable!
Que de critères déterministes!
Il arrive même que gcc fasse les tests d'un switch() par dichotomie...
On peut faire pratiquement tout en fait.
Même réordonner certains cases s'ils se terminent tous par un saut (mais là, j'ai des doutes sur la véritable utilité de cette manoeuvre).
SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.
"Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
Apparently everyone. -- Raymond Chen.
Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.
Je n'ai pas parle des boucles infinies, mais de celles dont on ne sait pas si elles se terminent.Envoyé par lun4t1k
Et alors?Envoyé par Jean-Marc.Bourguet
while (reste !== 0) ou for(; reste !== 0 ; ) ne facilitent pas le calcul! alors qu'ils terminent. Mais c'est sûr que de calculer la complexité d'un algo sans preuve de terminaison...
C'est tout ce que je voulais mettre en avant !
La condition, c'est:Envoyé par lun4t1k
Thierry
Code : Sélectionner tout - Visualiser dans une fenêtre à part while (reste != 0)
"The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
"If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow
FAQ-Python FAQ-C FAQ-C++
+
ça fait très très longtemps que je n'ai pas fait d'assembleur, et je n'ai pas regardé comment c'était décode par le compilo, mais le principe est très simple, il me semble :Envoyé par Ulmo
à chaque case une valeur :
donc normalement un jmp
Il est certain que si c'et la deuxième manière qui est utilisée, c'est beaucoup plus rapide
Pour la première, si c'est une valeur simple (la valeur d'un entier), il n'y a pas de différence. Par contre, dans la plupart des cas où c'est utilisé, ce n'est pas un test simple sur une valeur entière prédéfinie (une constante), mais une comparaison au minimum avec une variable, souvent plusieurs tests ensemble.
Normalement ceci devrait être équivalent :
Et
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 if ( i == 3 ) { } else if ( i == 2 ) { } else if ( i == 1 ) { }
Par contre , ceci ne devrait PAS être équivalent :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 switch ( i ) { case 1 : break ; case 2 : break ; case 3 : break ; }
et
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 if ( (j == var1) && (i == 3) ) { } else if ( (j == var2) && (i == 2) ) { } else if ( (j == var3) && (i == 1)) { }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 switch ( i ) { case 3 : if ( j == var3 ) { } break ; case 2 : if ( j == var2 ) { } break ; case 1 : if ( j == var1 ) { } break ; }
A mons avis....
Partager