2009-03-06 7 views
1

Je sais que la boxe est un concept populaire avec beaucoup d'informations disponibles à ce sujet, mais j'ai quelques questions que je ne peux pas vraiment trouver des réponses à:Questions sur la boxe

1) Si la boxe conduit à une valeur type (struct) étant converti en un objet (Type de référence), ou type de référence, alors pourquoi utiliser un type de valeur qui sera encadré et encourra une pénalité de performance? Je suis conscient des avantages et de la pertinence dans certains cas d'une structure ou d'une classe. On dit (1) que les valeurs (types de valeur) ont tendance à vivre sur la pile dans un espace de stockage temporaire, mais pour combien de temps? Si je n'ai pas besoin du type, comment puis-je m'assurer qu'il est pris en charge et éliminé à ce moment? Ou est-ce là où le modèle jetable entre en jeu? Je suppose que la raison d'utiliser une structure sera due à ses avantages. De manière intéressante, si j'utilise une structure pour stocker deux chaînes et un champ DateTime, la structure contiendra deux références (chaînes) et le DateTime ensemble. Je suppose évidemment que c'est plus rapide que les valeurs dispersées. Y a-t-il quelque chose que je dois savoir dans cette conception? (2).

1) http://en.csharp-online.net/Classes, Structs, and Objects—Boxing and Unboxing

2) http://dotnetperls.com/Content/Struct-Examples.aspx

je l'ai fait une recherche sur ici pour les réponses que je suis après, mais pas de chance. Je fais généralement des recherches sur ce site pour des sujets tels que GC, génériques, gestion des exceptions, etc., car il y a beaucoup de sagesse à apprendre et à partager.

Merci pour l'éducation (potentielle) à toutes les affiches! Veuillez excuser toute naïveté potentielle. Apprendre les internes m'amène à passer du temps à comprendre l'IL, etc. (quelque chose à aborder, bientôt).

Répondre

4

Si vous ne passez jamais le type de valeur dans une variable de référence, la boxe ne se produira pas. Lorsque vous ne savez pas, alors répondez aux questions suivantes questions:

  • Loi comme les types primitifs.
  • Avoir une taille d'instance inférieure à 16 octets.
  • Sont immuables.
  • La sémantique des valeurs est souhaitable.

Je considère aussi habituellement quelle est la durée de vie d'une telle variable. Si c'est une variable locale utilisée dans une méthode alors je tente d'utiliser struct (sinon class).

+0

Ceux-ci prennent de la.Lignes directrices NET et sont généralement de bonnes questions à vous poser. –

+0

J'entends toujours parler de la sémantique des valeurs - quel serait le moment où une telle chose est souhaitée? – dotnetdev

+0

http://msdn.microsoft.com/fr-fr/library/aa664472%28VS.71%29.aspx Parle de la sémantique des valeurs et de leur utilité. –

1

Vous devez utiliser des types de valeur en raison de leur avantage logique et non des gains de performance. Cela étant dit, parce que les types de valeur sont gérés sur la pile, n'ont pas besoin de participer à la récupération de place. Si vous avez un type qui est constamment créé et jeté (comme un int, float, double, etc), alors vous pouvez obtenir un bon coup de pouce en les transformant en structs. La chose à faire attention est que vous ne devriez vraiment considérer cela que si vous pouvez également rendre la structure immuable.

+0

Qu'est-ce qui est requis pour rendre une structure immuable? Ai-je raison de penser que je lui donne une faible visibilité et que je la mette en lecture seule? – dotnetdev

+0

En outre, comment l'élimination fonctionne-t-elle pour les types de valeur sur la pile de toute façon? – dotnetdev

+0

Malheureusement, il n'y a pas de sémantique en C# pour créer des types immuables. Il s'agit simplement de s'assurer que son état ne peut pas être changé après la création. –

0

Vous n'avez pas toujours besoin de boxe, et avec les génériques, vous n'avez pas besoin de cela.
La mémoire utilisée par les types de valeurs (struct est un type de valeur) sera revendiquée comme
dès que la méthode se termine/retourne et que vous n'avez rien à faire pour que cela se produise.

Les types de valeur déclarés comme membres d'instance seront en mémoire jusqu'à ce que l'objet
soit supprimé par le CPG.

Les types de référence sont conservés sur le tas géré.
Les types de référence instanciés dans une méthode seront supprimés par le garbage collector
lorsque aucun objet ne contient de référence. Le GC fonctionne de lui-même et la plupart du temps, vous devez le laisser seul.
Vous ne pouvez pas prédire quand un objet va être supprimé par le CPG.

Le modèle Dispose est utilisé sur les types de référence, mais ne forcera pas GC à supprimer
un objet. Il est généralement utilisé pour libérer des ressources non gérées.

Pour les valeurs de la pile considèrent comme suit:
Disons que vous avez un programme simple avec trois méthodes, comme ci-dessous:
Lorsque ce programme est exécuté, la méthode principale est exécutée, et ainsi de suite. S'il vous plaît suivre les
numéros ci-dessous:

 

Main 
{ 
    // (0) Stack is empty 
    int firstInt = 0; 
    // (1) Stack now contains: 
    //      firstInt 
    DoSomething1(); 
    // (7) Stack still contains: 
    //      firstInt 
} 
// Program ends 

DoSomething() 
{ 
    int anInteger = 0; 
    // (2) Stack now contains: 
    //     anInteger 
    //     firstInt 
    DoMore() 
    // (5) Stack now contains: 
    //      anInteger 
    //      firstInt 
} 
// (6) anInteger goes out of scope 

DoMore 
{ 
    int anotherInteger = 1; 
    // (3) Stack now contains: 
    //      anotherInteger 
    //      anInteger 
    //      firstInt 
} 
// (4) anotherInteger goes out of scope 

1

Un couple d'autres choses à considérer -

D'abord, vous voulez faire struct sûr sont immuables (en général). À cause de cela, c'est une bonne règle de ne pas avoir de structures contenant des types de référence. Les chaînes peuvent être une exception à cela car elles sont immuables en C#, mais en termes de règle générale pour le design, je m'en méfierais. Deuxièmement, il y a un autre cas d'utilisation pour les structs qui n'a pas été mentionné jusqu'à présent - un grand nombre de petits objets. Si vous avez une grande liste ou un tableau de petits objets, les structures fournissent une cohérence de cache considérablement meilleure et sont absolument critiques. C'est pourquoi la plupart des moteurs 3D utilisent des structures pour les points/vecteurs - ils ont tendance à avoir de grands réseaux de points, etc.

Ceci est quelque chose qui mérite d'être étudié si la performance est une partie importante de votre application. Par exemple, dans l'une de mes applications, le changement d'un type unique d'une classe à une structure a été réduit de 40% sur un processus de longue durée (> 5 minutes d'exécution). Avoir les objets proches les uns des autres en mémoire si vous les utilisez de manière répétée dans des calculs mathématiques lourds peut fournir des gains énormes. Maintenant, dans votre cas, avoir 2 chaînes et un DateTime ne verront probablement aucune amélioration à partir de cela. Le type de routines qui fonctionnerait sur les chaînes ne fait probablement pas de gros calculs (espérons-le), c'est-à-dire: transformer un demi-million de points dans l'espace, ou faire une grande matrice, etc .. .net3.5sp1 a rendu les structures beaucoup plus utiles. Avant 3.5sp1 (sur x86), il n'y avait pas d'inline de méthodes avec des appels struct. Cela a limité les gains de performance possibles via les structures. La mise à jour de votre framework peut rendre l'ancien code struct beaucoup plus rapide (dans certains cas).

+0

Si je regarde quels types sont la valeur et qui sont la référence, alors une struct travaillerait quelques types de valeur sélectionnés et tout le travail avec les types de référence qui se passe dans les classes. Donc, les types de référence (chaîne de caractères) sont immuables? – dotnetdev

+0

Fondamentalement, mais dans l'autre sens - Les types de référence sont normalement des types mutables, c'est-à-dire que les propriétés changent leurs valeurs (ensemble). Structs, d'autre part, serait immuable. Fondamentalement, une fois qu'une structure est construite, vous ne voulez jamais qu'elle change. Si vous voulez une nouvelle valeur, vous créez une nouvelle structure. –