Il existe des situations spécifiques où le fait de restreindre le type sous-jacent apporte certains avantages, par exemple en matière de performances ou pour forcer une disposition particulière de la mémoire lors de l'interfaçage avec du code non géré.
Considérez cet échantillon :
using System;
public enum Operations_PerHourType // : byte
{
Holes = 1,
Pieces = 2,
Sheets = 3,
Strips = 4,
Studs = 5
}
class Program
{
static void Main()
{
long before = GC.GetTotalMemory(false);
var enums = new Operations_PerHourType[10000];
long after = GC.GetTotalMemory(false);
Console.WriteLine(after - before);
// output (byte): 12218 (I'm using Mono 2.8)
// output (Int32): 40960
}
}
Ce code consomme environ 40 Ko du tas. Maintenant, spécifiez (dé-commentez) le type sous-jacent en tant que byte
et recompiler. Wow. Tout à coup, nous n'avons plus besoin que d'environ 10 Ko.
Compacter la mémoire de cette manière peut parfois rendre un programme plus lent, et non plus rapide, selon les modèles d'accès et les tailles de données. Il n'y a pas d'autre moyen d'en être sûr que de faire quelques mesures et d'essayer de généraliser à d'autres circonstances possibles. La traversée séquentielle de données plus petites est généralement plus rapide.
Cependant, prendre l'habitude de spécifier des types étroits simplement parce que c'est généralement possible et parfois crucial, n'est pas une bonne idée. Les économies de mémoire se matérialisent rarement en raison de l'alignement mémoire des types de données plus larges environnants. Les performances sont alors soit identiques, soit légèrement inférieures en raison des instructions supplémentaires nécessaires pour masquer les octets de remplissage.
Comme une autre réponse l'a déjà bien exprimé, suivez les Int32
Il s'agit d'une foule de personnes pour lesquelles le moteur d'exécution est optimisé, jusqu'à ce que vous deviez commencer à profiler et à traiter les véritables problèmes de mémoire dans votre application.