Frage

Hat jemand jemals tatsächlich verwendet stackalloc beim Programmieren in C#?Ich weiß, was es tut, aber das einzige Mal, dass es in meinem Code auftaucht, ist ein Zufall, weil Intellisense es vorschlägt, wenn ich mit der Eingabe beginne static, Zum Beispiel.

Obwohl es nichts mit den Nutzungsszenarien von zu tun hat stackalloc, ich führe in meinen Apps tatsächlich eine beträchtliche Menge an Legacy-Interop aus, sodass ich hin und wieder auf die Verwendung zurückgreifen könnte unsafe Code.Aber trotzdem finde ich normalerweise Möglichkeiten, es zu vermeiden unsafe vollständig.

Und da die Stapelgröße für einen einzelnen Thread in .Net ~1 MB beträgt (korrigieren Sie mich, wenn ich falsch liege), bin ich noch zurückhaltender gegenüber der Verwendung stackalloc.

Gibt es einige praktische Fälle, in denen man sagen könnte:„Das ist genau die richtige Menge an Daten und Verarbeitung, die ich unsicher machen und nutzen kann.“ stackalloc"?

War es hilfreich?

Lösung

Der einzige Grund stackalloc zu verwenden, ist die Leistung (entweder für Berechnungen oder Interop). Durch die Verwendung von stackalloc anstelle einem Heap-Array erstellen Sie weniger GC Druck (der GC braucht weniger zu laufen), brauchen Sie nicht die Arrays zu, es schneller ist als ein Haufen Array zuweisen, ein auf automatisch freigegeben wird Verfahren exit (Speicher zugeordnet Arrays werden nur freigegeben, wenn GC läuft). Auch von stackalloc anstelle eines nativen allocator mit (wie malloc oder .Net-Äquivalent) Sie gewinnen Geschwindigkeit und die automatische Aufhebung der Zuordnung auf Umfang zu verlassen.

Performance weise, wenn Sie stackalloc verwenden Sie groß die Wahrscheinlichkeit von Cache erhöhen Zugriffe auf die CPU aufgrund der Örtlichkeit von Daten.

Andere Tipps

Ich habe stackalloc verwendet zuzuteilen Puffer für [in der Nähe] Echtzeit-DSP-Arbeit. Es war ein sehr spezifischer Fall, in dem die Leistung so konsistent wie möglich sein mußte. Hinweis: Es gibt einen Unterschied zwischen Konsistenz und Gesamtdurchsatz - in diesem Fall, dass ich nicht mit Heap angehen Zuweisungen mit dem nicht Determinismus der Garbage Collection in dem Programm an diesem Punkt zu langsam, gerade zu sein. Ich würde es nicht in 99% der Fälle verwendet werden.

stackalloc ist nur für unsicheren Code relevant.Bei verwaltetem Code können Sie nicht entscheiden, wo Daten zugewiesen werden sollen.Werttypen werden standardmäßig auf dem Stapel zugewiesen (es sei denn, sie sind Teil eines Referenztyps. In diesem Fall werden sie auf dem Heap zugewiesen).Referenztypen werden auf dem Heap zugewiesen.

Die Standardstapelgröße für eine Plain-Vanilla-.NET-Anwendung beträgt 1 MB, Sie können dies jedoch im PE-Header ändern.Wenn Sie Threads explizit starten, können Sie über die Konstruktorüberladung auch eine andere Größe festlegen.Für ASP.NET-Anwendungen beträgt die Standardstapelgröße nur 256 KB. Dies sollten Sie im Hinterkopf behalten, wenn Sie zwischen den beiden Umgebungen wechseln.

stackalloc Initialisierung von Spannweiten. In früheren Versionen von C #, könnte das Ergebnis stackalloc nur in einen Zeiger lokalen Variable gespeichert werden. Wie von C # 7.2, kann stackalloc nun als Teil eines Ausdrucks verwendet werden und eine Spannweite ausrichten können, und das kann ohne Verwendung des unsicheren Schlüsselwort durchgeführt werden. So kann anstelle des Schreibens

Span<byte> bytes;
unsafe
{
  byte* tmp = stackalloc byte[length];
  bytes = new Span<byte>(tmp, length);
}

Sie können schreiben Sie einfach:

Span<byte> bytes = stackalloc byte[length];

Dies ist auch sehr nützlich in Situationen, in denen Sie einige Kratzer Platz benötigen, eine Operation auszuführen, wollen aber die Zuweisung Heap-Speichers zu vermeiden, für relativ kleine Größen

Span<byte> bytes = length <= 128 ? stackalloc byte[length] : new byte[length];
... // Code that operates on the Span<byte>

Quelle: C # - Alles über Span: Exploring eine neue .NET Main

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