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

vitesse d'execution

14 réponses
Avatar
AG
Bonjour,

d'aucun prétendent que :

int * p = malloc(10*sizeof(*p));
int i;

for(i=0;i<10;i++)
{
*p++=0;
}
p-=10;

est plus rapide que :

int * p = malloc(10*sizeof(*p));
int i;

for(i=0;i<10;i++)
{
p[i]=0;
}

Ce que je sais c'est que la première solution est peu lisible est pas trés
naturelle. La deuxième me parait bien plus simple, et idiomatique. Qu'en
est-il niveau rapidité ? le compilo n'est-il pas capable d'optimiser tout
seul ce genre de boucle ?

AG.

10 réponses

1 2
Avatar
Targeur fou
AG wrote:
Bonjour,


Salut,


d'aucun prétendent que :

int * p = malloc(10*sizeof(*p));
int i;

for(i=0;i<10;i++)
{
*p++=0;
}
p-;

est plus rapide que :

int * p = malloc(10*sizeof(*p));
int i;

for(i=0;i<10;i++)
{
p[i]=0;
}

Ce que je sais c'est que la première solution est peu lisible est pas t rés
naturelle. La deuxième me parait bien plus simple, et idiomatique. Qu'en
est-il niveau rapidité ? le compilo n'est-il pas capable d'optimiser to ut
seul ce genre de boucle ?


Bof, c'est tiré par les cheveux tout cela. C'est vraiment chercher la
petite bête, d'autant plus qu'avec l'exemple choisi, c'est le malloc()
qui risque de pénaliser le plus ici. A part regarder le code
assembleur généré par ton compilateur dans chaque cas, je ne vois
pas ce qu'il faut en conclure à propos de la capacité d'optimisation
d'un compilateur. Pour une telle tâche, j'utilise memset() ou
directement calloc(). En ce qui concerne le style et ce qui parait le
plus idiomatique, je trouve aussi que c'est la seconde version, ceci
dit, il y a celle-là aussi (qui me rappelle en passant le récent fil
sur l'ordonnancement des opérations ), qui économise la soustraction
sur le pointeur :

for(i=0; i<10; i++) {
*(p+i) = 0;
}

A+
Regis

Avatar
Pierre Maurette
AG wrote:
Bonjour,


Salut,


d'aucun prétendent que :

int * p = malloc(10*sizeof(*p));
int i;

for(i=0;i<10;i++)
{
*p++=0;
}
p-;

est plus rapide que :

int * p = malloc(10*sizeof(*p));
int i;

for(i=0;i<10;i++)
{
p[i]=0;
}

[...]


dit, il y a celle-là aussi (qui me rappelle en passant le récent fil
sur l'ordonnancement des opérations ), qui économise la soustraction
sur le pointeur :

for(i=0; i<10; i++) {
*(p+i) = 0;
}
Quelle est ou pourrait être la différence entre:


for(i=0; i<10; i++) {
*(p+i) = 0;
}

et

for(i=0;i<10;i++) {
p[i]=0;
}

???

Je veux dire: qu'est-ce que p[i], si ce n'est *(p+i) ?

--
Pierre Maurette


Avatar
Targeur fou
Pierre Maurette wrote:

Salut,

AG wrote:
Bonjour,


Salut,


d'aucun prétendent que :

int * p = malloc(10*sizeof(*p));
int i;

for(i=0;i<10;i++)
{
*p++=0;
}
p-;

est plus rapide que :

int * p = malloc(10*sizeof(*p));
int i;

for(i=0;i<10;i++)
{
p[i]=0;
}

[...]


dit, il y a celle-là aussi (qui me rappelle en passant le récent fil
sur l'ordonnancement des opérations ), qui économise la soustraction
sur le pointeur :

for(i=0; i<10; i++) {
*(p+i) = 0;
}
Quelle est ou pourrait être la différence entre:


for(i=0; i<10; i++) {
*(p+i) = 0;
}

et

for(i=0;i<10;i++) {
p[i]=0;
}

???

Je veux dire: qu'est-ce que p[i], si ce n'est *(p+i) ?


Fondamentalement, il n'y a bien sûr aucune différence (cf.
§6.5.2.1). Il s'agit uniquement de style d'écriture, pour ne pas
faire apparaître les crochets d'indiçage, i.e. une écriture plus
orientée arithmétique sur pointeur comme la première solution d'AG.
Je répète que pour un tel job je ne crois pas que le compilateur soit
à même d'optimiser plus l'une ou l'autre des solutions originales
proposées. memset() et calloc() font pour moi très bien l'affaire et
dans le contexte global d'une application, je ne pense pas que ce soit
sur des détails de ce genre que l'on gagne beaucoup en vitesse
d'exécution.

A+
Regis



Avatar
Pierre Maurette
Bonjour,

d'aucun prétendent que :

int * p = malloc(10*sizeof(*p));
int i;

for(i=0;i<10;i++)
{
*p++=0;
}
p-;

est plus rapide que :

int * p = malloc(10*sizeof(*p));
int i;

for(i=0;i<10;i++)
{
p[i]=0;
}

Ce que je sais c'est que la première solution est peu lisible est pas trés
naturelle.
La première si on en reste au code proposé a un petit défaut: le

pointeur retourné par malloc() n'est pas constant :-(
Je préfèrerais alors (en connaissant l'inutilité fréquente de
"register"):

int* const p = malloc(10*sizeof(*p));
register int* rp = p;
int i;
for(i=0;i<10;i++)
{
*rp++=0;
}

ou carrément:

int* const p = malloc(10*sizeof(*p));
register int* rp = p;
register int* rpend = rp + 10;
while(rp<rpend)*rp++=0;

La deuxième me parait bien plus simple, et idiomatique. Qu'en
est-il niveau rapidité ? le compilo n'est-il pas capable d'optimiser tout
seul ce genre de boucle ?
Je pense que le résultat sera le même dès que le compilateur ne sera

pas trop rustique. Bien entendu tout celà n'a un sens, y compris "le
même", que dans la mesure où 10 est remplacé par quelque chose de bien
plus consistant. Sinon, c'est le malloc() qu'il faut chronométrer.

--
Pierre Maurette

Avatar
Harpo
Pierre Maurette wrote:

Je veux dire: qu'est-ce que p[i], si ce n'est *(p+i) ?


"What's in a name? that which we call a rose
By any other name would smell as sweet;"
- W. Shakespeare R&J 2.2

--
http://harpo.free.fr/

Avatar
Harpo
AG wrote:

Bonjour,

d'aucun prétendent que :

int * p = malloc(10*sizeof(*p));
int i;

for(i=0;i<10;i++)
{
*p++=0;
}
p-;

est plus rapide que :

int * p = malloc(10*sizeof(*p));
int i;

for(i=0;i<10;i++)
{
p[i]=0;
}

Ce que je sais c'est que la première solution est peu lisible est pas
trés naturelle.


Ca se discute.

La deuxième me parait bien plus simple, et
idiomatique. Qu'en est-il niveau rapidité ? le compilo n'est-il pas
capable d'optimiser tout seul ce genre de boucle ?


très probablement 'si'.
Je préfèrerais quand même quelque chose de plus trivial
size_t i ;
for ( i = 10; i--; *(p+i) = 0):
C'est plus simple à comprendre.

--
http://harpo.free.fr/

Avatar
Emmanuel Delahaye
d'aucun prétendent que :

int * p = malloc(10*sizeof(*p));
int i;

for(i=0;i<10;i++)
{
*p++=0;
}
p-;


Horrible !

int * p = malloc (10 * sizeof *p);
if (p != NULL)
{
int * p_end = p + 10;

do
{
p_end--;
*p_end = 0;
}
while (p_end != p);
}

est plus rapide que :


<...>

Ce que je sais c'est que la première solution est peu lisible est pas trés
naturelle. La deuxième me parait bien plus simple, et idiomatique. Qu'en
est-il niveau rapidité ?


C'était peut être vrai du temps des dinosaures...

le compilo n'est-il pas capable d'optimiser tout
seul ce genre de boucle ?


... tout à fait.

--
A+

Emmanuel Delahaye

Avatar
Emmanuel Delahaye
Quelle est ou pourrait être la différence entre:

for(i=0; i<10; i++) {
*(p+i) = 0;
}

et

for(i=0;i<10;i++) {
p[i]=0;
}

???


Aucune.

Je veux dire: qu'est-ce que p[i], si ce n'est *(p+i) ?


Si.

--
A+

Emmanuel Delahaye

Avatar
Emmanuel Delahaye
int* const p = malloc(10*sizeof(*p));
register int* rp = p;
register int* rpend = rp + 10;
while(rp<rpend)*rp++=0;


J'ai failli proposer ça, et puis j'ai trouvé une solution décroissante
qui économise un pointeur.

--
A+

Emmanuel Delahaye

Avatar
Pierre Maurette
int* const p = malloc(10*sizeof(*p));
register int* rp = p;
register int* rpend = rp + 10;
while(rp<rpend)*rp++=0;


J'ai failli proposer ça, et puis j'ai trouvé une solution décroissante qui
économise un pointeur.
Ouf. La hiérarchie est sauve. Le respect d'une échelle de valeurs, y'a

que ça de vrai.

En tous cas, ça illustre l'utilité du "one past the last element".

--
Pierre Maurette


1 2