longueur - c# valeur int



Pourquoi devrais-je utiliser int au lieu d'un octet ou court en C# (5)

Au niveau performance, un int est plus rapide dans presque tous les cas. La CPU est conçue pour fonctionner efficacement avec des valeurs 32 bits.

Les valeurs plus courtes sont compliquées à gérer. Pour lire un seul octet, disons, le processeur doit lire le bloc de 32 bits qui le contient, puis masquer les 24 bits supérieurs.

Pour écrire un octet, il doit lire le bloc de 32 bits de destination, écraser les 8 bits inférieurs avec la valeur d'octet désirée et réécrire le bloc entier de 32 bits.

Dans l'espace, bien sûr, vous économisez quelques octets en utilisant des types de données plus petits. Donc, si vous construisez une table avec quelques millions de lignes, alors des types de données plus courts peuvent valoir la peine d'être considérés. (Et la même chose pourrait être une bonne raison pour laquelle vous devriez utiliser des types de données plus petits dans votre base de données)

Et du point de vue de la correction, un int ne déborde pas facilement. Que se passe-t-il si vous pensez que votre valeur va tenir dans un octet, et qu'à un certain moment dans le futur, un changement d'apparence inoffensive dans le code signifie que des valeurs plus grandes y seront stockées?

Ce sont quelques-unes des raisons pour lesquelles int devrait être votre type de données par défaut pour toutes les données intégrales. N'utilisez l'octet que si vous voulez réellement stocker les octets machine. N'utilisez des shorts que si vous utilisez un format de fichier ou un protocole ou similaire qui spécifie des valeurs entières de 16 bits. Si vous ne faites que traiter des entiers en général, faites-en des entiers.

J'ai trouvé quelques discussions sur ce problème. La plupart des gens semblent préférer utiliser int dans leur code c # à travers le tableau même si un byte ou un smallint gérerait les données sauf s'il s'agit d'une application mobile. Je ne comprends pas pourquoi. N'est-il pas plus logique de définir votre type de données C # comme le même type de données que dans votre solution de stockage de données?

Ma prémisse: Si j'utilise un jeu de données typé, des classes Linq2SQL, POCO, d'une manière ou d'une autre, je vais rencontrer des problèmes de conversion de type de compilateur si je ne synchronise pas mes types de données sur mes niveaux. Je n'aime pas vraiment faire System.Convert tout le temps juste parce qu'il était plus facile d'utiliser int en face à face dans le code c #. J'ai toujours utilisé le plus petit type de données nécessaire pour gérer les données dans la base de données ainsi que dans le code, pour garder mon interface à la base de données propre. Donc je parie que 75% de mon code C # utilise octet ou court par opposition à int, parce que c'est ce qui est dans la base de données.

Possibilités: Cela signifie-t-il que la plupart des gens qui utilisent int pour tout dans le code utilisent aussi le type de données int pour leurs types de données de stockage sql et se soucient peu de la taille globale de leur base de données?

Pourquoi je m'en soucie: j'ai travaillé pour toujours et je veux juste me familiariser avec les bonnes pratiques et les conventions de codage standard.


Ce n'est pas que je ne croyais pas Jon Grant et d'autres, mais je devais voir par moi-même avec notre "table de million de rangées". La table a 1,018,000. J'ai converti 11 colonnes tinyint et 6 smallint colonnes en int, il y avait déjà 5 int et 3 smalldatetimes. 4 index différents ont utilisé une combinaison des différents types de données, mais évidemment les nouveaux index utilisent maintenant des colonnes int.

Faire les changements ne m'a coûté que 40 Mo calculant l'utilisation du disque de table de base sans index. Quand j'ai ajouté les index dans le changement global était seulement 30 mb de différence globale. J'ai donc été surpris parce que je pensais que la taille de l'index serait plus grande.

Donc, 30 mb vaut la peine d'utiliser tous les différents types de données, No Way! Je pars pour la terre d'INT, merci à tous pour avoir placé ce programmeur rétentif anale sur la vie heureuse et heureuse de plus de conversions entières ... yippeee!


Je n'ai que 6 ans de retard mais peut-être que je peux aider quelqu'un d'autre.

Voici quelques lignes directrices que j'utiliserais:

  • S'il y a une possibilité que les données ne rentrent pas dans le futur, utilisez le type int plus grand.
  • Si la variable est utilisée en tant que champ struct / class, elle sera par défaut complétée pour occuper tout le 32 bits, donc l'utilisation de byte / int16 ne sauvera pas la mémoire.
  • Si la variable est de courte durée (comme dans une fonction), les types de données plus petits n'aideront pas beaucoup.
  • "byte" ou "char" peut parfois mieux décrire les données et peut compiler une vérification du temps pour s'assurer que des valeurs plus grandes ne lui sont pas attribuées accidentellement. Par exemple, si vous stockez le jour du mois (1-31) à l'aide d'un octet et essayez d'y affecter 1000, cela provoquera une erreur.
  • Si la variable est utilisée dans un tableau d'environ 100 ou plus, j'utiliserai le plus petit type de données tant que cela a du sens.
  • Les tableaux byte et int16 ne sont pas aussi sûrs que les threads int (une primitive).

Un sujet que personne n'a soulevé est le cache CPU limité. Les plus petits programmes s'exécutent plus vite que les plus grands parce que le CPU peut adapter plus de programme dans les caches L1 / L2 / L3 plus rapides.

L'utilisation du type int peut réduire le nombre d'instructions de l'UC, mais force également un pourcentage plus élevé de la mémoire de données à ne pas tenir dans le cache de l'UC. Les instructions sont bon marché à exécuter. Les cœurs de processeurs modernes peuvent exécuter 3 à 7 instructions par cycle d'horloge, mais un seul défaut de cache peut coûter de 1 000 à 2 000 cycles d'horloge car il doit aller jusqu'à la RAM.

Lorsque la mémoire est conservée, le reste de l'application fonctionne mieux car elle n'est pas supprimée du cache.

J'ai fait un test de somme rapide en accédant à des données aléatoires dans un ordre aléatoire en utilisant à la fois un tableau d'octets et un tableau int.

const int SIZE = 10000000, LOOPS = 80000;
byte[] array = Enumerable.Repeat(0, SIZE).Select(i => (byte)r.Next(10)).ToArray();
int[] visitOrder = Enumerable.Repeat(0, LOOPS).Select(i => r.Next(SIZE)).ToArray();

System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
sw.Start();
int sum = 0;
foreach (int v in visitOrder)
    sum += array[v];
sw.Stop();

Voici les résultats dans le temps (ticks): (x86, mode release, sans débogueur, .NET 4.5, I7-3930k) (plus petit est mieux)

________________ Array Size __________________
       10  100   1K   10K  100K    1M   10M 
byte: 549  559  552   552   568   632  3041  
int : 549  566  552   562   590  1803  4206
  • l'accès aléatoire aux éléments 1M en utilisant octet sur mon processeur a eu une augmentation de performance de 285%!
  • Rien de moins de 10 000 était à peine perceptible.
  • int n'a jamais été plus rapide que l'octet pour ce test de somme de base.
  • Ces valeurs seront très différentes avec des processeurs différents avec des tailles de cache différentes.

Une note finale, Parfois, je regarde le framework .NET open-source pour voir ce que font les experts de Microsoft. Le framework .NET utilise byte / int16 étonnamment peu. Je ne pouvais pas en trouver en fait.


L'environnement d'exécution .NET est optimisé pour Int32. Voir la discussion précédente à .NET Integer vs Int16?


Si int est utilisé partout, aucun casting ou conversion n'est requis. C'est un plus grand coup pour la somme que la mémoire que vous économiserez en utilisant plusieurs tailles entières.

Cela rend la vie plus simple.





types