2017-11-16 2 views
4

Angenommen, ich habe eine Webanwendung und möchte den neuen Typ Span<T> verwenden, um den GC-Druck zu reduzieren und die Leistung zu verbessern.Welche gemeinsamen Operationen können durch Span <T> effizienter gemacht werden?

Auf welche Muster sollte ich achten? Gibt es typische Vorgänge, an die das .NET-Team bei der Implementierung dieser neuen Funktion gedacht hat?

+3

https://blogs.msdn.microsoft.com/dotnet/2017/11/15/welcome-to-c-7-2-and-span/ oder http://adamsitnik.com/Span/ kann sein von Interesse. – mjwills

+1

[MSDN Magazin: C# 7.2: Span Video verstehen] (https://channel9.msdn.com/Events/Connect/2017/T125) –

+0

Wenn überhaupt, kann es die API vereinfachen. Ich mache viele Vektor-/Matrix-Operationen und bin begeistert, Speicher zu vereinheitlichen. Momentan habe ich verschiedene Klassen für nicht verwaltete ("feste") Punkte und verwaltete Arrays für den Speicher. – ja72

Antwort

2

Es gibt durchaus Fälle, in denen diese neue Klasse und Infrastruktur helfen kann, aber wenn sie üblich sind, hängt von Ihrem Code ...

Als Beispiel finden Sie in diesem Pre-C# 7.2 Implementierung:

static void Main(string[] args) 
{ 
    byte[] file = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8 }; 
    byte[] header = file.Take(4).ToArray(); 
    byte[] content = file.Skip(4).ToArray(); 

    bool isValid = IsValidHeader(header); 
} 

private static bool IsValidHeader(byte[] header) 
{ 
    return header[0] == 0 && header[1] == 1; 
} 

Die file.Take(4).ToArray() und byte[] content = file.Skip(4).ToArray(); sind das Problem hier: Wir müssen ein neues Array erstellen, nur um die beiden Teile des Byte-Arrays zu teilen. Wenn die Größe der Byte-Array, können Sie sich vorstellen, die Auswirkungen auf die Leistung und Speicherauslastung (stellen Sie sich ein 10 MB file Array, nimmt plötzlich 20 MB im Speicher).

nun die C# 7.2 Implementierung sehen:

static void Main(string[] args) 
{ 
    byte[] file = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8 }; 
    var header = file.Take(4); 
    var content = file.Skip(4); 

    bool isValid = IsValidHeader(header); 
} 

private static bool IsValidHeader(ReadOnlySpan<byte> header) 
{ 
    return header[0] == 0 && header[1] == 1; 
} 

Mit ReadOnlySpan<T> (Teil der Span<T> Infrastruktur) hier ist es möglich, die Daten in dem Array zu verwenden, ohne es zu duplizieren! Der Speicherdruck beträgt immer noch 10 MB. Das Array wird nicht dupliziert. Und da beide Arrays, Listen und Stream-Reader Span<T> verwenden, können Sie eine gemeinsame Methode für alle Quellen erstellen.

Natürlich könnte dies auch mit IEnumerable<T> implementiert werden, aber diese Leistung ist so viel besser (kein endloses Überspringen zum Beispiel, wenn Sie die Variable content wiederholt verwenden).

Verwandte Themen