2010-11-17 6 views
16

Il est souvent arrivé que vous sachiez que votre boucle n'exécutera jamais plus de x nombre de fois où x peut être représenté par un octet ou un court-circuit, essentiellement un type de données plus petit que int. Pourquoi utilisons-nous int qui prend 32 bits (avec la plupart des langues) quand quelque chose comme un octet suffirait ce qui est seulement 8 bits.Pourquoi un entier est-il toujours utilisé comme variable de contrôle dans une boucle for?

Je sais que nous avons des processus 32 bits et 64 bits, donc nous pouvons facilement récupérer la valeur en un seul passage, mais il consomme toujours plus de mémoire. Ou qu'est-ce qui me manque ici?

MISE À JOUR: Juste pour clarifier. Je suis conscient que la vitesse sage, il n'y a pas de différence. Je pose des questions sur l'impact sur la consommation de la mémoire.

+0

Vraiment? La plupart du code que j'ai vu utilise une forme de type non signé. –

+1

@Billy ONeal: Sur certains micros intégrés, un type non signé peut offrir de meilleures performances qu'un type signé, au prix d'une plus grande prudence avec la logique de terminaison de boucle. D'un autre côté, si un processeur comme un ARM stocke quelque chose comme uint16 dans un registre 32 bits, il doit ajouter du code supplémentaire pour "écrêter" la valeur à 16 bits. Aucun code de ce type ne serait nécessaire avec un int16 (puisque tout ce qui est autorisé à se produire quand un int16 est assigné une valeur en dehors de la plage -32768..32767, un compilateur pourrait juste laisser sa valeur faire ce qui est pratique). – supercat

+2

Est-ce que vous créez suffisamment de compteurs de boucle pour lesquels le changement de type a un effet * visible * sur la consommation de mémoire? Si c'est le cas, j'affirme que vous avez de plus gros problèmes que de simplement utiliser un type plus large que nécessaire. –

Répondre

27

En C, un est défini « int » comme type entier le plus efficace pour la machine actuelle.

Il correspond généralement aux registres de la CPU, c'est comme cela qu'il est le plus efficace.

L'utilisation d'un plus petit type de valeur entière peut entraîner une décalage de bit ou bit de masquage au niveau du processeur afin que vous obtenez aucun gain ...

+11

En fait, il est défini comme la «taille de mot naturel», qui peut ou peut ne pas être le type le plus efficace. Pour le type le plus efficace, utilisez fastint_t de C99. –

+1

Quelque chose à propos de la démystification de ces détails sur la programmation est réellement très excitant – sova

+0

Je demandais plus sur la consommation de mémoire. – uriDium

6

Dans de nombreux cas, le compteur de boucle consomme exactement un registre de processeur. Changer le type en un entier de 8 ou 16 bits ne change pas cela, car les registres ont une taille fixe (32 bits sur une plate-forme 32 bits, etc.).

Parfois, le compteur de boucle peut être placé dans la RAM, par ex. lorsque vous appelez une fonction de la boucle. Alors, oui, vous pouvez perdre quelques octets, mais généralement pas assez pour être inquiet. Stocker et charger le compteur de boucle peut en fait être plus lent lors de l'utilisation de quelque chose de différent d'un int.

8

L'accès à une taille d'entier de la même taille que la taille du mot natif sera le plus efficace. L'utilisation d'un octet nécessitera presque certainement autant d'espace que la taille du mot natif et nécessitera un déplacement et un masquage pour accéder, de sorte qu'il n'y a rien à gagner. En pratique, à moins d'avoir une boucle très, très grande ou des restrictions de temps sévères, cela ne fera pas beaucoup de différence.

Mais comme toujours, utiliser tout ce qui est plus lisible et référence/profil premier ...

+0

Je doute fortement qu'un compilateur optimisant n'allouerait pas simplement un 'int' de l'espace pour ce' char' si en fait le 'int' était plus efficace. OTOH, sur la plupart des architectures dont je suis conscient, il n'y a pas de différence de vitesse entre un 'int' et un' char'. –

7

J'utilise presque toujours int moins qu'il y ait une très bonne raison pas à, juste parce que tout le monde l'utilise toujours. Ceci afin d'éviter que le prochain développeur ne passe du temps à réfléchir Pourquoi n'a-t-il pas utilisé un int ici, y at-il une raison particulière que je dois savoir à propos de.

Le plus standard mon code est, le plus facile à lire dans le futur.

+1

Bon point. La plupart des gens connaissent et peuvent comprendre la syntaxe i ++, aussi. –

4

En termes de Java Language Specification il y a un point intéressant à noter sur l'utilisation de long et double:

Aux fins du modèle de mémoire de langage de programmation Java , une seule écriture à un non volatil long ou double valeur est traitée comme deux écritures distinctes : un à chaque 32 bits.Cela peut entraîner une situation où un thread voit les 32 premiers bits d'une valeur de 64 bits à partir d'une écriture, et les seconds 32 bits d'une autre écriture. Les écritures et les lectures des valeurs doubles volatiles et sont toujours atomiques. Les écritures et les lectures de références sont toujours atomiques, qu'elles soient implémentées en tant que valeurs 32 ou 64 bits . Les implémenteurs VM sont encouragés pour éviter de diviser leurs valeurs 64 bits si possible. Les programmeurs sont encouragés à déclarer valeurs partagées 64 bits comme volatiles ou de synchroniser correctement leurs programmes pour éviter complications possibles.

Il est clair que cela fait au moyen d'un long ou double dans votre variable boucle moins efficace qu'un int dans le modèle de mémoire Java, mais les implémentations peuvent varier en performance.

0

Je suis tenté d'ajouter quelque chose ici même si c'est un très vieux fil de discussion. Je ne suis pas entièrement d'accord avec "Je suis conscient que la vitesse sage, il n'y a pas de différence". En effet, très souvent en boucle il y a indexation de tableau comme dans

for (i=0; i<len; i++) s = A[i] 

Ensuite, même si votre tableau est de taille inférieure à 128, vous verrez une différence de vitesse notable si i est un int ou un byte. En effet, pour effectuer l'arithmétique de pointeur dans A[i] le processeur doit convertir votre entier en quelque chose qui a la même taille qu'un pointeur. Si l'entier a déjà la même taille, il n'y a pas de conversion qui induit un code plus rapide. Sur une machine 64 bits, j'ai l'impression que 20% d'accélération sur les programmes en utilisant long int pour les index de boucle sur très petit tableau au lieu de char (programmes C/C++).

+0

C'est intéressant. Merci – uriDium

Questions connexes