2017-11-16 10 views
23

C#7.2は、string[]のような以前のC#タイプよりも優れたパフォーマンスを持つSpan<T>Memory<T>の2つの新しいタイプを導入しています。C#7.2のスパン<T>とメモリ<T>の違いは何ですか?

質問:Span<T>Memory<T>の違いは何ですか?なぜ私はもう一方を使いましたか?

+3

も参照してください:[C#7.2:Understanding Span](https://channel9.msdn.com/Events/Connect/2017/T125) –

+1

@JeffMercado文字列の他に置き換えることができるC#タイプの完全なリストがありますか[]?それらは配列用であるか、リストのような型の代わりに使用できますか? – user3610374

答えて

22

Span<T>はスタックのみの性質であり、Memory<T>はヒープを使用できます。

Span<T>は、我々は[] Tと同等の性能 特性を有する任意のメモリの 連続領域を表すためにプラットフォームに追加する新しいタイプです。そのAPIは配列 に似ていますが、配列とは異なり、管理されたメモリまたはネイティブメモリを指すか、またはスタックに割り当てられたメモリに を割り当てることができます。

Memory <T>は、Span<T>を補完するタイプです。ドキュメント で説明されているように、Span<T>はスタックのみのタイプです。 Span<T>のスタックのみの性質は、ヒープ上のバッファへの参照(Span<T>で表される)を格納することを必要とする多くのシナリオでは不適切です。非同期呼び出しを行うルーチンの場合は です。

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; 
} 

この問題に対処するために、我々は、相補型のセットを提供します、 表す汎用交換タイプとして使用されることを意図し、 だけSpan <T>、任意のメモリの範囲等が挙げられるが、とは異なり、 Span <T> これらのタイプはスタック専用ではありませんが、メモリへの読み込みと書き込みのパフォーマンスが大幅に低下します( )。上記サンプルで

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; 
} 

Memory <byte>は、バッファを表すために使用されます。 これは通常型であり、非同期呼び出しを行うメソッドで使用できます。 SpanプロパティはSpan<byte>を返しますが、戻り値 は非同期呼び出し中にヒープに格納されませんが、 の新しい値はMemory<T>の値から生成されます。ある意味では Memory<T>Span<T>の工場です。

参考資料:here

+1

「スタックのみの性質」は何を意味しますか? – Enigmativity

+0

@コーディングはそうではありませんが、管理されたメモリ(つまり配列)を指すこともできます。スパンがスタック内にしか存在しないという事実は、それが指し示すメモリがスタックにあることを要求しているわけではありません。 –

+0

あなたが参照しているデザイン文書へのリンクを投稿してください。 –

10

再:これは、スタック上に割り当てられたメモリのみを指すことを意味します。

Span<T>は、スタックまたはヒープに割り当てられた任意のメモリを指すことができます。 Span<T>のスタックのみの性質は、Span<T>自体(それが指すメモリではない)がスタック上にのみ存在することができることを意味します。これは、(クラス/参照型に埋め込まれている)スタックまたはヒープ上に存在することができる "通常の" C#構造体とは対照的です。実際に最も明白な意味合いは、クラス内にSpan<T>フィールドを持つことができないことです。ボックスSpan<T>を使用することはできず、配列の内部に配置することはできません。

+0

ああ、それらのbyrefのようなタイプのもう一つ。 – IllidanS4

関連する問題