1

...de questions. Bah oui j'avais pas internet en vacances, alors j'ai tout soigneusement noté grin

C'est parti :

1) Comment allouer dynamiquement une structure après l'avoir déclaré comme ça ?

typedef struct
{
int tbl_pos[4],int_cmp,int_typ;
} BULLET;


BULLET variable[10]=malloc(10*sizeof(BULLET)) ne marche pas sad


2) Si j'ai deux tableaux de type int, est-il plus rapide d'écrire :

tbl1[0]=tbl2[0];
tbl1[1]=tbl2[1];
tbl1[2]=tbl2[2];
tbl1[3]=tbl2[3];


ou bien :

memcpy(tbl1,tbl2,8); ?


3) Dans une boucle 'for', est-il plus rapide d'écrire :

[i]for(i=0;i<50;i++)
{
if(tbl)
{
...
}
}


ou bien :

[i]for(i=0;i<50;i++)
{
if(!tbl) continue;
...
}


?
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

2

Bob 64 a écrit :

1) Comment allouer dynamiquement une structure après l'avoir déclaré comme ça ?

typedef struct
{
int tbl_pos[4],int_cmp,int_typ;
} BULLET;


BULLET variable[10]=malloc(10*sizeof(BULLET)) ne marche pas sad


fait:

BULLET *variable=malloc(10*sizeof(BULLET));

2) Si j'ai deux tableaux de type int, est-il plus rapide d'écrire :

tbl1[0]=tbl2[0];
tbl1[1]=tbl2[1];
tbl1[2]=tbl2[2];
tbl1[3]=tbl2[3];


ou bien :

memcpy(tbl1,tbl2,8); ?


si le tableau est petit, je pense que la premiere methode est plus rapide

3

1) Il me semble que si tu fais : BULLET *variable =malloc(10*sizeof(BULLET));

2) Je ne sais pas

3) Je ne sais pas mais j'aimerais bien connaître la réponse

4

Arg, j'avais préparé une réponse de fou pour la QUESTION 1 grin, vous avez posté avant, tant pis, je la met qd même ! grin


Non, pour les structures ! smile

Une allocation signifie qu'on va "réserver" un espace en RAM, d'une taille précise, et avec les fonctions appropriées comme calloc/malloc, on va obetnir l'adresse du 1er octet de cet espace alloué smile

Donc on récup l'adresse par un pointeur de type "ta structure" et pas avec un tableau wink

la bonne déclaration est :

#define NBRE_VAR_BULLET 10

BULLET *tab_struct_bullet = calloc(NBRE_VAR_BULLET, sizeof(BULLET));

et tu accèdes simplement à la x_ième structure par :

tab_struct_bullet[x-1] ou *(tab_struct_bullet + x - 1)

et à leur élement par :

tab_struct_bullet[x-1].element
ou
(tab_struct_bullet + x - 1)->element


PS : j'ai bien mis "x-1" pour coller à ma phrase "x_ième structure" étant donnée que le référencement des elements d'1 tableau commence à 0 en C wink
En pratique tu vires le "-1" évidemment, et tu fais gaffes que tu accèdes à ta 1ère structure par tab_struct_bullet[0].
PS bis : j'ai mis des noms très longs pour bien montrer, en vrai tu les raccourci un peu wink


Edit : Merci Jackie smile
Non-Webmaster et non-programmeur du site. .Pour tout probleme ou question ,débrouillez vous avec les Webmasters .

«- Pas Moo ! ^^

5

bon, hop une question dans le meme genre :
quest ce qui est le plus rapide quand on fait des opérations sur les elts de pleins de tableau dans une boucle
exemple

for (i=0,i<10,i++)
{

c[i]=a[i]+b[i]
... et plein d'opérations dans le meme genre...
}

c de laisse les tableux tels quels (c[i]=a[i]+b[i])
de faire une structure de tous ces tableux
struct { long a,b,c;} x;
et d'utiliser x[i].c=x[i].a+x[i].b

ou alors de charger l'elt i de chaque tableau dans une var et modifier cette var en la sauvant dans le tableau a la fin ?

ai=a[i];
bi=b[i];
ci=c[i];
...
c=a+b;
...
c[i]=c;
b[i]=b;
a[i]=a;

sachant qu'il y a un paque d'operations qui utilisent des tableau dans ma boucle
avatar

6

1) BULLET *variable=malloc(10*sizeof(BULLET))

2) Entre les deux, le plus rapide est a priori le 1er puisqu'il n'y a pas de temps d'initialisation, mais tu peux faire encore mieux :

#define inl_memcpy(a,b,s) ({typedef struct {char z[s];} __TS; (void)(*(__TS *)(a)=*(__TS *)(b));})

et il suffit alors d'utiliser inl_memcpy à la place de memcpy. C'est le compilo qui se charge de générer le code de copie, et donc il est optimisé pour être le plus petit (et rapide) possible smile

3) Déjà, si tu cherches la rapidité, n'écris surtout pas for (i=0;i<50;i++) !!!
Utilise :

i=50;
while (i--) {
...
}

C'est 10000 fois plus petit et plus rapide smile

Ensuite pour ta question, les deux génèrent exactement le même code en principe. La seule chose qui change est la lisibilité. Si tu as bcp de choses dans ton if, prend la 2è solution, sinon prend la 1è.

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

7

oups j'arrive un peu tard smile c pas une bonne idée d'ouvrir les fenêtres à l'avance smile

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

8

Merci quand même grin

Et aux autres aussi smile
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

9

merci aussi

mais ca doit etre optimisable tout ca, pasque le prog ne doit pas calculer 15000 fois la meme chose non ?
avatar

10

Pollux > ah oui ?? un for() est plus lent et plus gros qu'une initialisation et un while(var--) ??? arf, je vais modifier qq truc je sens, en gardant une petit macro pour faire un peu comme une for() pour la syntaxe smile
Non-Webmaster et non-programmeur du site. .Pour tout probleme ou question ,débrouillez vous avec les Webmasters .

«- Pas Moo ! ^^

11

Non, il n'y a normalement pas de différence si le compilateur n'est pas trop mauvais.
for (i=0; i<50; i++) devrait être optimisé en do ... while (i--) si i n'est pas utilisé dans la boucle. Il est de toute façon qu'on ne peux pas passer de l'un à l'autre facilement si i est utilisé.

12

for(i=50;i>0;i--) est tout aussi rapide que while smile
XLib v1.00 Powerrrrrrrrrrrrrrrrrrrr!

13

Pim89>
> ah oui ?? un for() est plus lent et plus gros qu'une initialisation et un while(var--) ??? > arf, je vais modifier qq truc je sens, en gardant une petit macro pour faire un peu comme une for() pour la syntaxe

En gros, le code type ressemble à ça :
for_loop:
  moveq #0,d0
loop
  cmp.w #50,d0
  bge quit
  ...
  addq.w #1,d0
  bra loop
quit
  rts

while_loop:
  moveq #49,d0
loop
  ...
  dbf d0,loop
  rts


Ca fait une énorme différence, surtout en vitesse...

JM>
> Non, il n'y a normalement pas de différence si le compilateur n'est pas trop mauvais.
for (i=0; i<50; i++) devrait être optimisé en do ... while (i--) si i n'est pas utilisé dans la boucle. Il est de toute façon qu'on ne peux pas passer de l'un à l'autre facilement si i est utilisé.

Ben déjà GTC est trop mauvais grin Et puis dans toutes les versions de TI-GCC que j'ai vues, les for généraient le code horrible qu'il y a plus haut sad Peut-être que c corrigé dans les dernières versions (ça fait depuis un bail que le mot 'for' n'existe plus dans mes progs smile), mais en tout cas le seul compilo que je connaisse qui fasse ça est Visual C++ (et puis si tu fais une boucle style for (i=0;i<n;i++) func(tab[i]), il remplace tab[i] par *p++ top)

Et puis la plupart des programmeurs qui utilisent for utilisent aussi tab[i] plutôt que *p++, donc ça peut pas être optimisé par le compilo sad

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

14

>>BULLET variable[10]=malloc(10*sizeof(BULLET));
Tu peux faire
BULLET *variable=malloc(10*sizeof(BULLET));
comme ils ont dit, ou tu peux faire:
BULLET variable[10];
Cette solution est meilleure parce que:
l'espace est alloué sur la pile, donc il ne faut pas le faire libre. Ou, la même chose:
BULLET *variable=alloca(10*sizeof(BULLET));
Ça alloue l'espace sur la pile, aussi. Si tu peux, essaie d'éviter malloc ou HeapAllocPtr (c'est le même que malloc), parce que la ram sera réduite.

15

> le faire libre
on dit 'le libérer' ou 'le rendre libre' smile

> Si tu peux, essaie d'éviter malloc ou HeapAllocPtr (c'est le même que malloc), parce que la ram sera réduite
Ben ça dépend, si tu veux exécuter d'autre progs ou si ton truc est récursif, ton prog peut foirer embarrassed

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

16

azerty83 a écrit :
bon, hop une question dans le meme genre :
quest ce qui est le plus rapide quand on fait des opérations sur les elts de pleins de tableau dans une boucle
exemple

for (i=0,i<10,i++)
{

c[i]=a[i]+b[i]
... et plein d'opérations dans le meme genre...
}

c de laisse les tableux tels quels (c[i]=a[i]+b[i])
de faire une structure de tous ces tableux
struct { long a,b,c;} x;
et d'utiliser x[i].c=x[i].a+x[i].b

ou alors de charger l'elt i de chaque tableau dans une var et modifier cette var en la sauvant dans le tableau a la fin ?

ai=a[i];
bi=b[i];
ci=c[i];
...
c=a+b;
...
c[i]=c;
b[i]=b;
a[i]=a;
sachant qu'il y a un paque d'operations qui utilisent des tableau dans ma boucle


bon déjà :
- il faut virer le for et mettre un while (i--)
- il faut utiliser int *p=a,*q=b,*r=c, et dans la boucle :
*p++=(*q++)+(*r++)

Pour répondre à ta q, les 2 méthodes sont équivalentes dans ce cas précis, à condition que tu utilises des pointeurs comme je t'ai dit ci-dessus, mais je pense que TI-GCC optimisera moins bien la 2è solution donc la 1è est un poil meilleure. Mais dès que tu as plus de 2 ou 3 pointeurs, il vaut mieux utiliser des structures (nb de regs limité sad)

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

17

oui merci, je vais utiliser des pointeurs smile

(j'y avais pensé entre temps)
avatar

18

Pollux >> il vaut donc mieux ne pas utiliser tab[i] ds un while mais plutôt un pointeur sur ce tableau qu'on incrémente/décrémente ?
Non-Webmaster et non-programmeur du site. .Pour tout probleme ou question ,débrouillez vous avec les Webmasters .

«- Pas Moo ! ^^

19

oui..
pointeur optimisé en (a0)+ etc.. ou addq dans le pire des cas.
puis permet d'optimiser en un dbcc..

mais tu peux toujours faire un for.. le but c'est de faire une comparaisons avec 0 et non un autre chiffre
XLib v1.00 Powerrrrrrrrrrrrrrrrrrrr!

20

J'en apprend pas mal aujourd'hui smile, je suis un vrai boulet en optimisation vitesse (et mémoire aussi grin).
Je sais à peu près coder mais alors l'optimisation roll. y'a qu'à voir mes fonctions d'affichage qui sont en gros toutes des :

for()
XGNSprite(); ...

grin 5 for qui s'enchainent, c pas super rapide d'après ce que Pollux à dit.

Aussi j'ai regardé un code TIGCC avec d'abord une for() et ensuite une initialisation+ while(), et là taille du prog est la même à l'arrivée ds le TIOS smile j'ai pas maté le *.s pour vérifier que le code était semblable, mais en tt cas il prend la même place, peut-être que TIGCC dernière version optimise les for() smile
Non-Webmaster et non-programmeur du site. .Pour tout probleme ou question ,débrouillez vous avec les Webmasters .

«- Pas Moo ! ^^

21

oui c possible... mais si tu utilises le compteur i, je ne pense pas qu'il optimise smile (vérifie aussi que t'as bien mis qqch dans la boucle grin)

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

22

et est-ce qu'il faut déclarer les compteurs dans les boucles comme 'register' ?
avatar

23

non, le compilo est assez grand pour le déterminer tout seul smile

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

24

quel luxe cool
grin
avatar

25

NOTE IMPORTANTE :

j'ai testé les optimisations for() => initialisation + (while ou do {}while(); ) et en fait ça marche terrible ! eek

d'un truc comme
for(i=0: i<nbre_perso; i++)
{
  [3]/* mon code*/[/3]
}

passé à :

i = nbre_perso;
while(i)
{
  i--; [3]// nb : mettre while(i--) au début coute plus en place que de faire le test tt court 
ds le while() et ensuite décrémenter ds la boucle, j'ai regardé 
et j'ai donc laissé la décrémentation là[/3]
  [3]/* mon code*/[/3]
}


je gagne 8 octets en place rien que pour ça ! eek bon, après faut faire gaffe que ds notre prog, "partir de 0 et aller à nbre_perso" ne change rien ds la gestion à "partir de nbre_perso et aller à 0" wink moi ça change rien de traiter d'abord les dernier perso pour arriver au 1er perso, donc c cool cool

note : si vous êtes sur que nbre_perso >=1, vous pouvez même passer à :

i = nbre_perso;
do
{
  i--; [3]// i-- ici, raison : cf plus haut[/3]
  [3]/* mon code*/[/3]
}while(i);


et là on gagne 4 octets de plus qu'un simple while ! eek soit en tout 12 octets de plus que la for() de départ ! smile
attention je dis >=1, car le test == 0 du while() n'est fait qu'une fois les instructions de la boucle effectuées une fois au minimum, et on sait jamais, si vous faites un truc du genre tab[i] et que i = -1 (car au début il était égal à 0, soit non >=1), ben ça va pas le faire pour la suite, enfin ds mon code précisemment smile

Donc si la var d'initialisation est >=1, mettez la méthode do {} while(); , si elle est inférieure à 1 (cad 0 par exemple), mettez plutôt while(i) {} car le test est fait au début, donc pas de prob, les instructions de la boucle ne seront pas executées ! smile


PS : ça marche pas à tous les coups par contre, vérifier bien boucle par boucle que la modif fait gagner de la place, chez moi bizarement pour 1 seule boucle, j'ai rien gagné en place, mais partout ailleurs c 'était + 8 octets ! smile

RIEN A VOIR :

si on met au début du prog :

void mafonction(void); [3]// déclare au tt début avant _main[/3]

et après _main :

void mafonction(void)
{
  [3]/* le code*/[/3]
}


est ce que "mafonction" sera obligatoirement incluse ds le prog principal, même si elle n'est appelée à AUCUN endroit dans les autres fonctions du programme ?
car j'avais une fonction comme ça ds mon prog , je l'avais remplacé par une nouvelle (d'un autre nom), mais je l'avais laissé cette 1ère par oubli, et en la virant tt à l'heure, j'ai gagné 1 Ko, et en la remettant je pers 1 Ko.
Normalement, si une fonction est appelée NULLE PART, elle n'est pas incluse au prog lors de la compilation non ? ben là on dirait que si en fait (TIGCC 0.94 b 18).
Je me trompe ?
Non-Webmaster et non-programmeur du site. .Pour tout probleme ou question ,débrouillez vous avec les Webmasters .

«- Pas Moo ! ^^

26

> // nb : mettre while(i--) au début coute plus en place que de faire le test tt court
> ds le while() et ensuite décrémenter ds la boucle, j'ai regardé
> et j'ai donc laissé la décrémentation là
Hum, c un bug de TI-GCC ça, avec GTC while (i--) est plus court que while (i) i-- smile
c possible qu'ils le corrigent un jour, et alors tu seras obligé de changer ton prog smile
i = nbre_perso;
do
{
i--; // i-- ici, raison : cf plus haut
/* mon code*/ }while(i);

NEIN !!!
i = nbre_perso-1;
do {
 ...
} while (i--);

Là par contre TI-GCC l'optimise correctement, et c encore bcp plus rapide et plus petit que l'autre solution... smile
Et par pitié pour GTC ne faites pas i=nbre_perso; i--; parce que GTC n'optimise pas les expressions séparées (because ça ralentirait énormément)

> chez moi bizarement pour 1 seule boucle, j'ai rien gagné en place
tu utilisais i ?
est ce que "mafonction" sera obligatoirement incluse ds le prog principal, même si elle n'est appelée à AUCUN endroit dans les autres fonctions du programme ?
car j'avais une fonction comme ça ds mon prog , je l'avais remplacé par une nouvelle (d'un autre nom), mais je l'avais laissé cette 1ère par oubli, et en la virant tt à l'heure, j'ai gagné 1 Ko, et en la remettant je pers 1 Ko.
Normalement, si une fonction est appelée NULLE PART, elle n'est pas incluse au prog lors de la compilation non ? ben là on dirait que si en fait (TIGCC 0.94 b 18). Je me trompe ?

Oui grin Une fonction inutilisée est quand même générée (sauf dans certains cas, mais bon smile)

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

27

for(i=0: i<nbre_perso; i++)
{
/* mon code*/
}


=>

for(i=nbre_perso: i>0; i--)
{
/* mon code*/
}

c'est moins chian a modifier et c'est aussi rapide.
XLib v1.00 Powerrrrrrrrrrrrrrrrrrrr!

28

ok smile

Pollux >> pour le do {}while(i--); j'y avais pas pensé car j'étais resté ds la logique du while() simple et de la décrémentation, et là TIGCC n'optimisait pas. wink
Non-Webmaster et non-programmeur du site. .Pour tout probleme ou question ,débrouillez vous avec les Webmasters .

«- Pas Moo ! ^^

29

TiMad a écrit :
for(i=0: i<nbre_perso; i++)
{
/* mon code*/
}


=>

for(i=nbre_perso: i>0; i--)
{
/* mon code*/
}
c'est moins chian a modifier et c'est aussi rapide.


je dirais plutôt :
for(i=nbre_perso; i--wink
{
/* mon code*/
}

Ta version est moins optimisée...

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

30

ps...
tu parlessmile
l'optimisation n'existe passmile
c'est comme x+=1; x=x+1; et x++; le code généré sera addq #1,dx.. (je pense..)
XLib v1.00 Powerrrrrrrrrrrrrrrrrrrr!