89 votes

Structures et classes

Je suis sur le point de créer 100 000 objets dans le code. Ils sont de petite taille, seulement avec 2 ou 3 propriétés. Je vais les mettre dans une liste générique et quand ils le sont, je vais boucle de contrôle et la valeur a et peut-être mettre à jour la valeur b.

Est-il plus vite ou mieux pour créer ces objets de la classe ou structure?

MODIFIER

un. Les propriétés sont des types de valeur (à l'exception de la chaîne, je pense?)

b. Ils pourraient (nous ne sommes pas encore sûr) ont une méthode de validation

EDIT 2

Je me demandais: y a des objets sur le tas et la pile traité de la même façon par le garbage collector, ou cela fonctionne-t-il différent?

129voto

Eric Lippert Points 300275

est-il plus rapide pour créer ces objets de la classe ou structure?

Vous êtes la seule personne qui peut déterminer la réponse à cette question. Essayez les deux méthodes, une mesure significative, l'utilisateur ciblé, pertinent de mesure de performances, et alors vous saurez si le changement a un effet significatif sur les utilisateurs réels dans les scénarios.

Les structures de consommer moins de mémoire dans la mémoire (parce qu'ils sont plus petits et plus facilement compacté, non pas parce qu'ils sont "sur la pile"). Mais ils prennent plus de temps à copier qu'un exemplaire de référence. Je ne sais pas ce que vos indicateurs de performance sont pour l'utilisation de la mémoire ou de la vitesse; il y a un compromis à trouver ici, et vous êtes la personne qui sait ce que c'est.

est-il mieux de créer ces objets de la classe ou structure?

Peut-être de la classe, peut-être struct. Comme une règle de base: si l'objet est (1), (2) logiquement une valeur immuable, et (3) il y en a beaucoup alors je vous envisagez de faire une struct. Sinon, je collerais avec un type de référence.

Si vous avez besoin de muter certains champs d'une structure, il est généralement préférable de construire un constructeur qui renvoie une toute nouvelle structure avec l'ensemble de champs correctement. C'est peut-être un peu plus lent (le mesurer!) mais, logiquement, beaucoup plus facile de raisonner sur.

sont des objets sur le tas et la pile traité de la même façon par le garbage collector?

Non, ils ne sont pas les mêmes parce que les objets sur la pile sont les racines de la collection. Le garbage collector n'a pas besoin de demander "est-ce chose sur la pile en vie?" car la réponse à cette question est toujours "Oui, c'est sur la pile". (Maintenant, vous ne pouvez pas compter sur elle pour garder un objet vivant parce que la pile est un détail d'implémentation. La gigue est autorisé à introduire des optimisations que, disons, les enregister ce qui serait normalement une pile de valeur, et puis il n'est jamais sur la pile de sorte que le GC ne sait pas qu'il est encore vivant. Un enregistered objet peut avoir ses descendants recueillies de façon agressive, dès que le registre de s'y accrocher ne va pas être lu à nouveau.)

Mais le garbage collector n' ont à traiter des objets sur la pile en tant que vivant, de la même manière qu'il traite n'importe quel objet connu pour être vivant en tant que vivant. L'objet sur la pile peut se référer à allouées sur la pile des objets qui ont besoin d'être gardé en vie, de sorte que le GC a pour traiter la pile d'objets de la vie allouées sur la pile d'objets aux fins de la détermination du vivre ensemble. Mais, évidemment, ils sont pas traités comme des "objets vivants" pour l'application de compactage le tas, parce qu'ils ne sont pas sur le tas, en premier lieu.

Est-ce clair?

22voto

ja72 Points 9417

Parfois avec struct vous n'avez pas besoin d'appeler le nouveau() constructeur, et affecter directement les champs, ce qui rend beaucoup plus rapide que d'habitude.

Exemple:

Value[] list = new Value[N];
for (int i = 0; i < N; i++)
{
    list[i].id = i;
    list[i].is_valid = true;
}

est d'environ 2 à 3 fois plus rapide que

Value[] list = new Value[N];
for (int i = 0; i < N; i++)
{
    list[i] = new Value(i, true);
}

Value est struct avec deux champs (id et is_valid).

Sur l'autre main est les éléments que doit être déplacé ou sélectionné des types de valeur tout ce que la copie va vous ralentir. Pour obtenir la réponse exacte, je soupçonne que vous avez à faire le profil de votre code et de le tester.

18voto

GSerg Points 33571

Une liste retourne une copie de la structure. Mise à jour il exigerait <strike>désolidarisé de la liste et ajouter à nouveau,</strike> créant une copie neuve avec de nouvelles valeurs et en l’assignant à la liste des index.

Par conséquent, il est préférable d’utiliser des classes.

Concernant la lecture : http://stackoverflow.com/questions/441309/why-are-mutable-structs-evil

7voto

kyndigs Points 2452

Les structures peuvent sembler similaires aux classes, mais il y a des différences importantes que vous devez être conscients de. Tout d'abord, les classes sont des types référence et les structures sont des types de valeur. En utilisant les structures, vous pouvez créer des objets qui se comportent comme les types intégrés et de profiter de leurs avantages.

Lorsque vous appelez le Nouvel opérateur sur une classe, il sera alloué sur le tas. Toutefois, lorsque vous instanciez un struct, il est créé sur la pile. Cela offrira des gains de performance. Aussi, vous ne serez pas traiter avec des références à une instance d'un struct comme vous le feriez avec des classes. Vous travaillerez directement avec la structure de l'instance. De ce fait, lors du passage d'une structure à une méthode, il est passé par valeur et non comme une référence.

Plus ici:

http://msdn.microsoft.com/en-us/library/aa288471(SV.71).aspx

6voto

Paul Ruane Points 12840

Des tableaux de structures sont représentées sur le tas dans un bloc contigu de mémoire, alors qu'un tableau d'objets est représentée par un bloc contigu de références avec les objets réels eux-mêmes d'ailleurs sur le tas, ce qui nécessite de la mémoire pour les objets et de leurs références de tableau.

Dans ce cas, comme vous le plaçant dans un List<> (et un List<> est appuyée sur un tableau), il serait plus efficace de la mémoire sage d'utiliser des structures.

(Attention cependant, que de grands tableaux à trouver leur chemin sur le Tas d'Objets Volumineux où, si leur durée de vie est longue, pourrait avoir une incidence défavorable sur votre processus de gestion de la mémoire. Rappelez-vous, aussi, que la mémoire n'est pas la seule considération.)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X