Frage

Ich weiß, dass Box ein beliebtes Konzept mit vielen Informationen über sie, aber ich habe ein paar Fragen, die ich nicht wirklich Antworten finden kann:

1) Wenn Box auf einen Wert-Typen (struct führen) zu einem Objekt (Referenz Typ umgewandelt werden), oder Referenztyp, warum dann einen Werttyp verwendet werden, die eingerahmt werden und eine Leistungseinbuße entstehen? Ich bin mir bewusst, der Nutzen und Eignung in bestimmten Fällen entweder einer Struktur oder Klasse. Es wird gesagt, dass (1) Werte (Werttypen) sind in der Regel auf dem Stapel in einem temporären Speicherplatz leben, aber wie lange? Wenn ich den Typen nicht benötigen, wie kann ich sicherstellen, es versorgt und in diesem Moment angeordneten genommen wird? Oder ist dies, wo das Einweg-Muster ins Spiel kommt? Ich gehe davon aus, den Grund, eine Struktur zu verwenden, um seinen Vorteil fällig.

Interessanterweise, wenn ich eine Struktur verwenden, um zwei Zeichenketten zu speichern und ein Datetime-Feld, wird die Struktur zwei Referenzen (Strings) und die Datetime zusammenhalten. Ich gehe davon aus offensichtlich dies ist schneller als die Werte gestreut zu werden. Gibt es etwas, ich brauche von in diesem Entwurf bewusst zu sein? (2).

1) http: //en.csharp-online .net / Klassen, Strukturen und Objekte-Boxen und Unboxing

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

Ich habe für die Antworten auf hier eine Suche getan, was ich nach bin, aber kein Glück. Ich mache in der Regel sucht auf dieser Seite für Themen wie GC, Generika, Ausnahmebehandlung, etc., wie es eine Menge Weisheit ist, zu lernen und zu teilen.

Vielen Dank für die (potentielle) Bildung für alle Poster! Bitte entschuldigen Sie mögliche Naivität. die Interna nimmt mich schön zu verbringen einige Zeit lernen IL auf dem Verständnis, etc. (etwas in Angriff zu nehmen, bald).

War es hilfreich?

Lösung

Wenn Sie nie den Wert Typ in eine Referenzgröße passieren dann auftreten Boxen nicht. Wenn Sie nicht wissen, dann beantworten Sie die folgenden Fragen :

  • Act wie primitive Typen.
  • Haben Sie eine Instanz Größe unter 16 Bytes.
  • Sind unveränderlich.
  • Wert Semantik sind wünschenswert.

Darüber hinaus halte ich in der Regel, was die Lebensdauer eines solchen variabel ist. Handelt es sich um eine lokale Variable in einer Methode verwendet, dann würde ich Zelt Struktur zu verwenden (sonst Klasse).

Andere Tipps

Sie sollten Werttypen verwenden wegen ihrer logischen Vorteil, nicht die Performance-Gewinne. Davon abgesehen, weil Werttypen auf dem Stack verwaltet werden, brauchen nicht in die Garbage Collection teilnehmen. Wenn Sie einen Typ haben, die ständig erstellt und verworfen wird (wie ein int, float, double, etc), dann kann man einen guten Schub erhalten, indem diese in structs drehen. Die Sache vorsichtig zu sein, ist, dass Sie nur das wirklich überlegen, ob Sie auch die Struktur unveränderlich machen.

Ein paar andere Dinge zu beachten -

Als erstes wollen Sie sicher structs unveränderlich sind (im Allgemeinen) machen. Aus diesem Grunde ist es eine gute Daumenregel nicht structs haben Referenztypen enthalten. Strings kann eine Ausnahme von dieser Regel sein, da sie in C # unveränderlich sind, aber in Bezug auf einen Mehrzweckdaumenregel für Design, würde ich vorsichtig davon sein.

Zweitens gibt es einen anderen Anwendungsfall für structs, die bisher nicht erwähnt wurde - eine große Anzahl von kleinen Objekten. Wenn Sie eine große Liste oder ein Array von kleinen Objekten haben, bietet structs dramatisch besser Cache-Kohärenz und ist absolut entscheidend. Dies ist, warum die meisten 3D-Motoren Verwendung structs für Punkte / Vektoren -. Sie große Arrays von Punkten für Scheitelpunkte zu haben, neigen dazu, etc

Das ist etwas wert Aufmerksamkeit auf, wenn die Leistung ist ein wichtiger Teil Ihrer Anwendung. Zum Beispiel in einem meiner apps, rasierte einen einzigen Typ von einer Klasse zu einer Struktur zu ändern 40% gegenüber einem langen Lauf (> 5 Minuten Laufzeit) Prozess. die Objekte dicht beieinander in Speichern, wenn man sie immer wieder in schweren mathematischen Berechnungen verwenden, kann riesige Gewinne liefern.

Nun - in Ihrem Fall mit 2 Saiten und einem Datetime wahrscheinlich keine Verbesserungen von diesem sehen. Die Art von Routinen, die auf Zeichenkette funktionieren würden tun wahrscheinlich keine schwere Berechnung (hoffentlich), dh: a. Eine halbe Million Punkte im Raum umzuwandeln, oder eine große Matrix-Lösung zu tun, etc

Endlich - werden Sie feststellen, dass .net3.5sp1 gemacht structs bemerken viel nützlicher. Vor 3.5sp1 (x86), gibt es kein inlining von Methoden mit struct Anrufen. Dies begrenzt die Leistungsgewinne möglich über structs. Ihren Rahmen der Aktualisierung kann alten struct Code viel, viel schneller (in bestimmten Fällen) machen.

Sie haben nicht immer Boxen benötigen, und mit Generika gibt es wenig Notwendigkeit.
Der Speicher verwendet von Werttypen (struct ist ein Wert, Typ) werden als geltend gemacht werden
sobald die Methode / Returns endet und Sie nicht
müssen für das tun, etwas passieren.
Werttypen wie beispielsweise Mitglieder erklärt werden, bis das Objekt
in Erinnerung sein wird von der GC gelöscht.
Referenztypen werden auf dem verwalteten Heap gehalten.
Referenztypen innerhalb einer Methode instanziiert wird vom
gelöscht Garbage Collector, wenn kein Objekt einen Verweis auf sie hält.

GC Werke selbst und zum größten Teil sollten Sie es in Ruhe lassen.
Sie können nicht vorhersagen, wann ein Objekt durch die GC gelöscht werden wird.

Das Entsorgen Muster wird auf Referenztypen verwendet, aber nicht GC zwingen, zu löschen
ein Objekt. Es ist in der Regel zu freien nicht verwalteten Ressourcen verwendet.

Für Werte im Stapel Folgendes beachten:
Angenommen, Sie haben ein einfaches Programm mit drei Methoden haben, wie unten:
Wenn dieses Programm ausgeführt wird, wird das Hauptverfahren läuft, und so weiter. Bitte beachten Sie die
unter Nummern:


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

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top