2009-04-02 7 views
0

Je suis juste curieux et ne trouve pas la réponse n'importe où. Habituellement, nous utilisons un entier pour un compteur dans une boucle, par ex. en C/C++:Est-ce que cela change la performance pour utiliser un compteur non-int dans une boucle?

for (int i=0; i<100; ++i) 

Mais on peut aussi utiliser un entier court ou même char. Ma question est: Est-ce que ça change la performance? C'est quelques octets de moins donc les économies de mémoire sont négligeables. Cela m'intrigue juste si je fais un mal en utilisant un char si je sais que le compteur ne dépassera pas 100.

Répondre

1

Non, cela ne devrait vraiment pas affecter la performance. Il est probable que l'utilisation de la taille de l'entier «naturel» pour la plate-forme permettra d'obtenir les meilleures performances.

9

En C++, c'est généralement int. Cependant, la différence est susceptible d'être faible et vous ne trouverez probablement pas que c'est le goulot d'étranglement de la performance.

+0

Cela arrive parfois cependant. Sur un titre récent, le profileur m'a dit que nous dépensions 7% de CPU dans l'itérateur pour une classe de conteneur omniprésente. Lors de l'enquête, j'ai trouvé qu'il utilisait un short pour son type d'index; le changer à un int frappé cette fonction ci-dessous 1%. – Crashworks

1

Il aurait probablement été plus rapide de taper un programme rapide (vous avez déjà fait la ligne la plus complexe) et de la profiler, que de poser cette question ici. :-)

FWIW, dans les langages qui utilisent par défaut bignums (Python, Lisp, etc.), je n'ai jamais vu de profil où un compteur de boucles était le goulot d'étranglement. La vérification de la balise de type n'est pas si chère - quelques instructions au plus - mais probablement plus grande que la différence entre un (fix) int et un short int.

1

Probablement pas aussi longtemps que vous ne le faites pas avec un float ou un double. Étant donné que la mémoire est bon marché, vous devriez probablement utiliser un int.

2

Je ne peux pas fournir une citation, mais j'ai entendu dire que vous faites souvent un peu de frais généraux de performance en utilisant un court ou un caractère.

Les économies de mémoire sont inexistantes car il s'agit d'une variable de pile temporaire. La mémoire dans laquelle il vit sera presque certainement déjà allouée, et vous n'économiserez probablement rien en utilisant quelque chose de plus court car la variable suivante voudra probablement être alignée sur une plus grande limite de toute façon.

2

Vous pouvez utiliser n'importe quel type légal dans un pour; il ne doit pas être intégré ou même construit, par exemple, vous pouvez utiliser itérateurs ainsi:.

for(std::vector<std::string>::iterator s = myStrings.begin(); myStrings.end() != s; ++s) 
{ 
... 
} 

Si oui ou non elle aura un impact sur la performance se résume à une question de la façon dont les opérateurs vous l'utilisation sont mises en œuvre. Donc, dans l'exemple ci-dessus, cela signifie que end(), operator! =() Et operator ++().

3

Dépend de l'architecture. Sur le PowerPC, il y a généralement une pénalité de performance énorme impliquée dans l'utilisation de quelque chose d'autre que int (ou quelle que soit la taille du mot natif) - par exemple, n'utilisez pas short ou char. Float est juste dehors, aussi.

Vous devriez chronométrer ceci sur votre architecture particulière parce qu'elle varie, mais dans mes cas de test il y avait un ralentissement d'environ 20% de l'utilisation de court au lieu de int.

1

Un non signé ou size_t devrait, en théorie, vous donner de meilleurs résultats (wow, gens faciles, nous essayons d'optimiser pour le mal, et contre ceux qui crient «absurdité» prématurée.C'est la nouvelle tendance).

Cependant, il a ses inconvénients, principalement le classique: le vissage.

Google devs semble l'éviter mais c'est pita de lutter contre std ou boost.

+1

Sur quelles architectures non signées donner de meilleurs résultats? –

2

Ce n'est pas vraiment une réponse. J'explore juste ce que Crashworks a dit au sujet du PowerPC. Comme d'autres l'ont déjà fait remarquer, l'utilisation d'un type qui correspond à la taille du mot natif devrait produire le code le plus court et la meilleure performance.

$ cat loop.c 
extern void bar(); 

void foo() 
{ 
    int i; 

    for (i = 0; i < 42; ++i) 
     bar(); 
} 

$ powerpc-eabi-gcc -S -O3 -o - loop.c 
. 
. 
.L5: 
     bl bar 
     addic. 31,31,-1 
     bge+ 0,.L5 

Il est tout à fait différent avec short i, au lieu de int i, et ressemble ne fonctionnera pas comme bien non plus.

.L5: 
     bl bar 
     addi 3,31,1 
     extsh 31,3 
     cmpwi 7,31,41 
     ble+ 7,.L5 
0

Si vous compilez votre programme avec l'optimisation (par exemple, gcc -O), cela n'a pas d'importance. Le compilateur alloue un registre entier à la valeur et ne le stocke jamais en mémoire ou sur la pile. Si votre boucle appelle une routine, gcc va allouer l'une des variables r14-r31 que toute routine appelée sauvegardera et restaurera. Donc, utilisez int, car cela cause le moins de surprise à quiconque lit votre code.

Questions connexes