Vous devez presque toujours utilice Int32
o Int64
(et, non, vous n'obtenez pas de crédit en utilisant UInt32
o UInt64
) lors du bouclage d'un tableau ou d'une collection par index.
La raison la plus évidente pour laquelle il est moins efficace est que tous les index de tableaux et de collections trouvés dans la BCL prennent Int32
donc une distribution implicite est toujours va se produire dans le code qui essaie d'utiliser Int16
en guise d'index.
La raison la moins évidente (et la raison pour laquelle les tableaux prennent Int32
comme un indice) est que la spécification CIL dit que toutes les valeurs de la pile d'opérations sont soit Int32
o Int64
. Chaque fois que vous chargez ou stockez une valeur dans un autre type d'entier ( Byte
, SByte
, UInt16
, Int16
, UInt32
ou UInt64
), une opération de conversion implicite est impliquée. Les types non signés n'ont pas de pénalité pour le chargement, mais pour le stockage de la valeur, cela équivaut à une troncature et à un éventuel contrôle de débordement. Pour les types signés chaque Le signe de la charge s'étend, et le signe du magasin s'effondre (et il y a un contrôle de débordement possible).
L'endroit où cela va vous nuire le plus est la boucle elle-même, pas les accès aux tableaux. Par exemple, prenez cette boucle d'apparence innocente :
for (short i = 0; i < 32000; i++) {
...
}
Ça a l'air bien, non ? Pas du tout ! Vous pouvez en fait ignorer l'initialisation ( short i = 0
) puisqu'elle ne se produit qu'une fois, mais la comparaison ( i<32000
) et d'incrémentation ( i++
) se produisent 32000 fois. Voici un code pesudo pour montrer à quoi ressemble cette chose au niveau de la machine :
Int16 i = 0;
LOOP:
Int32 temp0 = Convert_I16_To_I32(i); // !!!
if (temp0 >= 32000) goto END;
...
Int32 temp1 = Convert_I16_To_I32(i); // !!!
Int32 temp2 = temp1 + 1;
i = Convert_I32_To_I16(temp2); // !!!
goto LOOP;
END:
Il y a 3 des conversions là-dedans qui sont exécutées 32000 temps. Et ils auraient pu être complètement évités en utilisant simplement une Int32
o Int64
.
Mise à jour : Comme je l'ai dit dans le commentaire, j'ai maintenant, en fait, écrit un article de blog sur ce sujet, Les types de données intégrales de .NET et vous