Hat jemand jemals tatsächlich stackalloc
beim Programmieren in C # verwendet? Ich weiß, was getan wird, aber das einzige Mal, dass es in meinem Code angezeigt wird, ist ein Zufall, da Intellisense dies beispielsweise vorschlägt, wenn ich mit der Eingabe beginne static
.
Obwohl es nicht mit den Nutzungsszenarien von zusammenhängt stackalloc
, mache ich tatsächlich eine beträchtliche Menge an Legacy-Interop in meinen Apps, sodass ich von Zeit zu Zeit auf die Verwendung von unsafe
Code zurückgreifen kann. Trotzdem finde ich normalerweise Wege, dies unsafe
vollständig zu vermeiden .
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 bei der Verwendung stackalloc
.
Gibt es einige praktische Fälle, in denen man sagen könnte: "Dies ist genau die richtige Menge an Daten und Verarbeitung, damit ich unsicher werde und sie verwende stackalloc
"?
quelle
System.Numbers
es viel verwendet wird referencesource.microsoft.com/#mscorlib/system/…Antworten:
Der einzige Grund für die Verwendung
stackalloc
ist die Leistung (entweder für Berechnungen oder Interop). Wenn Siestackalloc
anstelle eines Heap-zugewiesenen Arrays weniger GC-Druck erzeugen (der GC muss weniger ausgeführt werden), müssen Sie die Arrays nicht festnageln. Die Zuweisung ist schneller als bei einem Heap-Array und wird bei der Methode automatisch freigegeben exit (Heap-zugewiesene Arrays werden nur freigegeben, wenn GC ausgeführt wird). Durch die Verwendungstackalloc
eines nativen Allokators (wie malloc oder des .Net-Äquivalents) erhalten Sie außerdem Geschwindigkeit und automatische Freigabe beim Beenden des Bereichs.In Bezug auf die Leistung
stackalloc
erhöhen Sie bei Verwendung die Wahrscheinlichkeit von Cache-Treffern auf der CPU aufgrund der Datenlokalität erheblich.quelle
Ich habe Stackalloc verwendet, um Puffer für [fast] Echtzeit-DSP-Arbeit zuzuweisen. Es war ein sehr spezifischer Fall, in dem die Leistung so konstant wie möglich sein musste. Beachten Sie, dass es einen Unterschied zwischen Konsistenz und Gesamtdurchsatz gibt. In diesem Fall ging es mir nicht darum, dass die Heap-Zuweisungen zu langsam sind, sondern nur darum, dass die Garbage Collection zu diesem Zeitpunkt im Programm nicht deterministisch ist. Ich würde es in 99% der Fälle nicht verwenden.
quelle
stackalloc
ist nur für unsicheren Code relevant. Für verwalteten Code können Sie nicht entscheiden, wo Daten zugeordnet 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 einfache Vanille-.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 ist zu beachten, wenn Sie zwischen den beiden Umgebungen wechseln.
quelle
Stackalloc-Initialisierung von Spannen. In früheren Versionen von C # konnte das Ergebnis von stackalloc nur in einer lokalen Zeigervariablen gespeichert werden. Ab C # 7.2 kann Stackalloc jetzt als Teil eines Ausdrucks verwendet werden und auf eine Spanne abzielen. Dies kann ohne Verwendung des unsicheren Schlüsselworts erfolgen. Also anstatt zu schreiben
Sie können einfach schreiben:
Dies ist auch in Situationen äußerst nützlich, in denen Sie zum Ausführen eines Vorgangs etwas Arbeitsbereich benötigen, aber die Zuweisung von Heap-Speicher für relativ kleine Größen vermeiden möchten
Quelle: C # - Alles über Span: Erkunden einer neuen .NET-Hauptstütze
quelle
Span
ist es in .NET Framework 4.7.2 und sogar nicht in 4.8 leider nicht verfügbar ... Daher ist diese neue Sprachfunktion im Moment noch von begrenztem Nutzen.Diese Frage enthält einige gute Antworten, aber ich möchte nur darauf hinweisen
Stackalloc kann auch zum Aufrufen nativer APIs verwendet werden
Bei vielen nativen Funktionen muss der Aufrufer einen Puffer zuweisen, um das Rückgabeergebnis zu erhalten. Beispielsweise hat die Funktion CfGetPlaceholderInfo in
cfapi.h
die folgende Signatur.Um es in C # über Interop aufzurufen,
Sie können stackalloc verwenden.
quelle