Question

J'ai une pratique de codage discutable.

Lorsque je dois parcourir une petite liste d'éléments dont le nombre limite est inférieur à 32000, j'utilise Int16 pour mon type de variable i au lieu de Integer. Je le fais parce que je suppose que l’utilisation de <=> est plus efficace qu’un <=> complet.

Est-ce que je me trompe? Existe-t-il une différence de performance réelle entre l’utilisation d’un <=> vs d’un <=>? Devrais-je cesser d'utiliser <=> et me contenter de <=> pour tous mes besoins en comptage / itération?

Était-ce utile?

La solution

Selon la référence ci-dessous, le runtime optimise les performances de Int32 et les recommande pour les compteurs et autres opérations fréquemment consultées.

Extrait du livre: Trousse de formation personnalisée des SCTM (examen 70-536): Microsoft & # 174; .NET Framework 2.0 & # 8212; Fondation pour le développement d'applications

Chapitre 1: ". Principes fondamentaux du cadre ".

Leçon 1: & "Utiliser les types de valeur &";

  

Meilleures pratiques: optimiser les performances   avec types intégrés

     

Le moteur d'exécution optimise les performances des types entiers 32 bits (Int32 et UInt32). Utilisez donc ces types pour les compteurs et autres variables intégrales fréquemment utilisées.

     

Pour les opérations en virgule flottante, Double est le type le plus efficace, car ces opérations sont optimisées par le matériel.

En outre, le tableau 1-1 de la même section répertorie les utilisations recommandées pour chaque type. Pertinent pour cette discussion:

  • Int16 - Interopération et autres utilisations spécialisées
  • Int32 - Nombres entiers et compteurs
  • Int64 - Grands nombres entiers

Autres conseils

Vous devez presque toujours utiliser Int32 ou Int64 (et, non, vous ne recevez pas de crédit en utilisant UInt32 ou UInt64) lorsque vous passez en boucle sur un tableau ou une collection. 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 Int16 s, de sorte qu'une conversion implicite est toujours dans le code qui tente de l'utiliser. Byte est un index.

La raison moins évidente (et la raison pour laquelle les tableaux prennent SByte en tant qu'index) est que la spécification CIL indique que toutes les valeurs de pile d'opérations sont soit UInt16 ou short i = 0. . Chaque fois que vous chargez ou stockez une valeur dans un autre type entier (i<32000, i++, <=>, <=>, <=>, <=> ou <=>), une opération de conversion implicite est impliquée. Les types non signés n'ont aucune pénalité pour le chargement, mais pour stocker la valeur, cela équivaut à une troncature et à une éventuelle vérification de débordement. Pour les types signés , chaque chargement de sign-étend et chaque magasin de sign-collaps (et a une vérification de débordement possible).

Ce qui vous fera le plus mal, c’est la boucle elle-même et non le tableau. Par exemple, prenez cette boucle d'aspect innocent:

for (short i = 0; i < 32000; i++) {
    ...
}

Ça a l'air bien, non? Nan! Vous pouvez fondamentalement ignorer l'initialisation (<=>) car cela ne se produit qu'une seule fois, mais la comparaison (<=>) et l'incrémentation (<=>) se produisent 32 000 fois. Voici un code pesudo pour ce à quoi cette chose ressemble 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 existe des 3 conversions exécutées 32000 . Et ils auraient pu être complètement évités en utilisant simplement un <=> ou <=>.

Mise à jour: Comme je l'ai dit dans le commentaire, je viens d'écrire un article sur ce sujet, .Les types de données .NET Integral et vous

Int16 peut en réalité être moins moins efficace, car les instructions x86 pour l’accès aux mots occupent plus de place que les instructions pour l’accès à dword. Cela dépendra de ce que fait l'ECE. Mais quoi qu'il en soit, ce n'est certainement pas plus efficace lorsqu'il est utilisé comme variable dans une itération.

Le contraire est vrai.

Les entiers à 32 (ou 64 bits) sont plus rapides que int16. En général, le type de données natif est le plus rapide.

Int16 sont bien si vous voulez rendre vos structures de données aussi minces que possible. Cela économise de l'espace et peut améliorer les performances.

Toute différence de performances sur un matériel moderne sera si minime que cela ne fera pratiquement aucune différence. Essayez d’écrire quelques faisceaux de test et exécutez-les tous les deux plusieurs centaines de fois, prenez le temps moyen d'achèvement de la boucle et vous verrez ce que je veux dire.

Du point de vue du stockage, il peut être judicieux de disposer de ressources très limitées - systèmes intégrés avec une pile minuscule, protocoles filaires conçus pour les réseaux lents (par exemple, GPRS, etc.), etc. ".

N'assumez jamais l'efficacité.

Ce qui est ou n'est pas plus efficace variera d'un compilateur à l'autre et d'une plate-forme à l'autre. À moins que vous n’ayez réellement testé cela, il n’existe aucun moyen de savoir si int16 ou int est plus efficace.

Je ne ferais que rester avec ints, sauf si vous rencontrez un problème de performances éprouvé qui corrige l'utilisation de solutions int16.

Utilisez Int32 sur les ordinateurs 32 bits (ou Int64 sur les ordinateurs 64 bits) pour des performances optimales. Utilisez un type entier plus petit si vous êtes vraiment préoccupé par l'espace qu'il occupe (peut être plus lent, cependant).

Les autres ici sont corrects, utilisez seulement inférieur à Int32 (pour le code 32 bits) / Int64 (pour le code 64 bits) si vous en avez besoin pour des exigences de stockage extrêmes ou pour un autre niveau. d’application sur un champ d’objet métier (vous devez bien entendu toujours avoir la validation du niveau de propriété dans ce cas).

Et en général, ne vous souciez pas de l'efficacité tant qu'il n'y a pas de problème de performances. Et dans ce cas, profilez-le. Et si devinez & Amp; vérifier avec les deux méthodes pendant que le profilage ne vous aide pas assez, vérifiez le code IL.

Bonne question cependant. Vous en apprenez plus sur la façon dont le compilateur fait sa chose. Si vous voulez apprendre à programmer plus efficacement, apprendre les bases de l’IL et la façon dont les compilateurs C # / VB font leur travail serait une excellente idée.

Je ne peux pas imaginer un gain de performance significatif sur Int16 vs. int.

Vous enregistrez des bits dans la déclaration de variable.

Et cela ne vaut vraiment pas la peine lorsque les spécifications changent et que quoi que vous comptiez puisse aller au-dessus de 32767 maintenant et vous découvrez que, lorsque votre application commence à générer des exceptions ...

L'utilisation d'un type de données inférieur à Int32 n'apporte aucun gain de performances significatif. En fait, j'ai lu quelque part que l'utilisation d'Int32 serait plus rapide que Int16 en raison de l'allocation de mémoire

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top