Jaka jest różnica między span a pamięcią w C # 7.2?

C # 7.2 wprowadza dwa nowe typy: Span<T> i Memory<T>, które mają lepszą wydajność niż wcześniejsze typy C#, takie jak string[].

Pytanie: Jaka jest różnica między Span<T> a Memory<T>? Dlaczego miałbym używać jednego nad drugim?

Author: Rand Random, 2017-11-16

2 answers

Span<T> jest naturą stosu, podczas gdy Memory<T> może używać stosu.

Span<T> jest nowym typem, który dodajemy do platformy, aby reprezentować sąsiadujących ze sobą regionów pamięci dowolnych, z wydajnością Charakterystyka na równi z T[]. Jego API są podobne do tablicy, ale w przeciwieństwie do tablic, może wskazywać na pamięć zarządzaną lub natywną, lub do pamięci przydzielonej na stosie.

Memory <T> jest typem uzupełniającym Span<T>. Jak omówiono w jego konstrukcji dokument, Span<T> jest Typ tylko stosu. Stos-tylko charakter Span<T> sprawia, że nie nadaje się do wielu scenariuszy wymagających przechowywania odwołania do buforów (reprezentowanych przez Span<T>) na stercie, np. dla procedury wykonujące połączenia asynchroniczne.

async Task DoSomethingAsync(Span<byte> buffer) {
    buffer[0] = 0;
    await Something(); // Oops! The stack unwinds here, but the buffer below
                       // cannot survive the continuation.
    buffer[0] = 1;
}

Aby rozwiązać ten problem, dostarczymy zestaw komplementarnych typów, przeznaczone do stosowania jako typy giełd ogólnego przeznaczenia reprezentujące, podobnie jak Span <T>, zakres arbitralnej pamięci, ale w przeciwieństwie do Span <T> tego typu nie będzie stack-tylko, kosztem znacznej kary wydajnościowe za odczyt i zapis do pamięci.

async Task DoSomethingAsync(Memory<byte> buffer) {
    buffer.Span[0] = 0;
    await Something(); // The stack unwinds here, but it's OK as Memory<T> is
                       // just like any other type.
    buffer.Span[0] = 1;
}

W powyższej próbce Memory <byte> jest używany do reprezentowania bufora. Jest to typ regularny i może być stosowany w metodach wykonujących asynchroniczne telefony. Jego właściwość Span zwraca Span<byte>, ale zwracana wartość nie jest zapisywany na stercie podczas asynchronicznych wywołań, ale raczej nowe wartości są wytwarzane z wartości Memory<T>. W pewnym sensie, Memory<T> jest fabryką Span<T>.

Dokument referencyjny: tutaj

 34
Author: Coding,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-22 14:11:58

Re: oznacza to, że może wskazywać tylko na pamięć przydzieloną na stosie.

Span<T> może wskazywać na dowolną pamięć: przydzieloną na stosie lub na stercie. Stack-only natura Span<T> oznacza, że sama Span<T> (nie pamięć, na którą wskazuje) może znajdować się tylko na stosie. Jest to przeciwieństwo "normalnych" struktur C#, które mogą znajdować się na stosie lub na stercie (gdy są osadzone w klasach/typach referencyjnych). Najbardziej oczywiste praktyczne implikacje to to, że nie można mieć Span<T> pola w class, nie można box Span<T> i nie można umieścić ich wewnątrz tablic.

 23
Author: Krzysztof Cwalina,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-20 18:34:35