Span<T> 構造体
定義
重要
一部の情報は、リリース前に大きく変更される可能性があるプレリリースされた製品に関するものです。 Microsoft は、ここに記載されている情報について、明示または黙示を問わず、一切保証しません。
任意のメモリの連続した領域のタイプ セーフでメモリ セーフな表現を提供します。
generic <typename T>
public value class Span
public readonly ref struct Span<T>
[System.Runtime.InteropServices.Marshalling.NativeMarshalling(typeof(System.Runtime.InteropServices.Marshalling.SpanMarshaller<,>))]
public readonly ref struct Span<T>
type Span<'T> = struct
[<System.Runtime.InteropServices.Marshalling.NativeMarshalling(typeof(System.Runtime.InteropServices.Marshalling.SpanMarshaller<,>))>]
type Span<'T> = struct
Public Structure Span(Of T)
型パラメーター
- T
内 Span<T>の項目の種類。
- 継承
- 属性
注釈
Span<T>
はマネージド ヒープではなく、スタックに割り当てられるref 構造体です。 ref 構造体は、ボックス化できない、Object、dynamic
または任意のインターフェイス型の変数に割り当てられない、参照型のフィールドにできない、await
やyield
をまたいで使用できないなど、マネージド ヒープに昇格しないようにするためのいくつかの制限があります。 さらに、Equals(Object)とGetHashCodeの2つのメソッドを呼び出すと、NotSupportedExceptionをスローします。
重要
Span<T>
はスタック専用の型であるため、ヒープ上でバッファーへの参照を格納する必要のある、多くのシナリオには適していません。 たとえば、非同期メソッドの呼び出しを行うルーチンなどが当てはまります。 このようなシナリオでは、補完的なSystem.Memory<T>とSystem.ReadOnlyMemory<T>型を使用できます。
不変、または読み取り専用の構造を表すスパンの場合、System.ReadOnlySpan<T>を使用してください。
スパン<T> とメモリ
Span<T>
は任意のメモリの連続した領域を表します。 Span<T>
インスタンスは、配列の要素または配列の一部を保持するためによく使用されます。 ただし、配列とは異なり、Span<T>
インスタンスは、マネージド メモリ、ネイティブ メモリ、スタック上で管理されたメモリを指すことができます。 次の例では、配列からSpan<Byte>
を作成します。
// Create a span over an array.
var array = new byte[100];
var arraySpan = new Span<byte>(array);
byte data = 0;
for (int ctr = 0; ctr < arraySpan.Length; ctr++)
arraySpan[ctr] = data++;
int arraySum = 0;
foreach (var value in array)
arraySum += value;
Console.WriteLine($"The sum is {arraySum}");
// Output: The sum is 4950
// Create a span over an array.
let array = Array.zeroCreate<byte> 100
let arraySpan = Span<byte> array
let mutable data = 0uy
for i = 0 to arraySpan.Length - 1 do
arraySpan[i] <- data
data <- data + 1uy
let mutable arraySum = 0
for value in array do
arraySum <- arraySum + int value
printfn $"The sum is {arraySum}"
// Output: The sum is 4950
次の例では、ネイティブ メモリの 100 バイトからSpan<Byte>
を作成します。
// Create a span from native memory.
var native = Marshal.AllocHGlobal(100);
Span<byte> nativeSpan;
unsafe
{
nativeSpan = new Span<byte>(native.ToPointer(), 100);
}
byte data = 0;
for (int ctr = 0; ctr < nativeSpan.Length; ctr++)
nativeSpan[ctr] = data++;
int nativeSum = 0;
foreach (var value in nativeSpan)
nativeSum += value;
Console.WriteLine($"The sum is {nativeSum}");
Marshal.FreeHGlobal(native);
// Output: The sum is 4950
// Create a span from native memory.
let native = Marshal.AllocHGlobal 100
let nativeSpan = Span<byte>(native.ToPointer(), 100)
let mutable data = 0uy
for i = 0 to nativeSpan.Length - 1 do
nativeSpan[i] <- data
data <- data + 1uy
let mutable nativeSum = 0
for value in nativeSpan do
nativeSum <- nativeSum + int value
printfn $"The sum is {nativeSum}"
Marshal.FreeHGlobal native
// Output: The sum is 4950
次の例では、 C#のstackallocキーワードを用いて、スタック上に 100 バイトのメモリを割り当てます。
// Create a span on the stack.
byte data = 0;
Span<byte> stackSpan = stackalloc byte[100];
for (int ctr = 0; ctr < stackSpan.Length; ctr++)
stackSpan[ctr] = data++;
int stackSum = 0;
foreach (var value in stackSpan)
stackSum += value;
Console.WriteLine($"The sum is {stackSum}");
// Output: The sum is 4950
// Create a span on the stack.
let mutable data = 0uy
let stackSpan =
let p = NativeInterop.NativePtr.stackalloc<byte> 100 |> NativeInterop.NativePtr.toVoidPtr
Span<byte>(p, 100)
for i = 0 to stackSpan.Length - 1 do
stackSpan[i] <- data
data <- data + 1uy
let mutable stackSum = 0
for value in stackSpan do
stackSum <- stackSum + int value
printfn $"The sum is {stackSum}"
// Output: The sum is 4950
は任意のメモリ ブロックに対する抽象化であるため Span<T>
、型のメソッドとパラメーターを Span<T>
持つ Span<T>
メソッドは、カプセル化するメモリの種類に関係なく、任意 Span<T>
のオブジェクトで動作します。 たとえば、スパンを初期化して、その要素を合計するコードの各セクションは、次の例のように単一の初期化メソッドと計算メソッドに変更できます。
public static void WorkWithSpans()
{
// Create a span over an array.
var array = new byte[100];
var arraySpan = new Span<byte>(array);
InitializeSpan(arraySpan);
Console.WriteLine($"The sum is {ComputeSum(arraySpan):N0}");
// Create an array from native memory.
var native = Marshal.AllocHGlobal(100);
Span<byte> nativeSpan;
unsafe
{
nativeSpan = new Span<byte>(native.ToPointer(), 100);
}
InitializeSpan(nativeSpan);
Console.WriteLine($"The sum is {ComputeSum(nativeSpan):N0}");
Marshal.FreeHGlobal(native);
// Create a span on the stack.
Span<byte> stackSpan = stackalloc byte[100];
InitializeSpan(stackSpan);
Console.WriteLine($"The sum is {ComputeSum(stackSpan):N0}");
}
public static void InitializeSpan(Span<byte> span)
{
byte value = 0;
for (int ctr = 0; ctr < span.Length; ctr++)
span[ctr] = value++;
}
public static int ComputeSum(Span<byte> span)
{
int sum = 0;
foreach (var value in span)
sum += value;
return sum;
}
// The example displays the following output:
// The sum is 4,950
// The sum is 4,950
// The sum is 4,950
open System
open System.Runtime.InteropServices
open FSharp.NativeInterop
// Package FSharp.NativeInterop.NativePtr.stackalloc for reuse.
let inline stackalloc<'a when 'a: unmanaged> length : Span<'a> =
let voidPointer = NativePtr.stackalloc<'a> length |> NativePtr.toVoidPtr
Span<'a>(voidPointer, length)
let initializeSpan (span: Span<byte>) =
let mutable value = 0uy
for i = 0 to span.Length - 1 do
span[i] <- value
value <- value + 1uy
let computeSum (span: Span<byte>) =
let mutable sum = 0
for value in span do
sum <- sum + int value
sum
let workWithSpans () =
// Create a span over an array.
let array = Array.zeroCreate<byte> 100
let arraySpan = Span<byte> array
initializeSpan arraySpan
printfn $"The sum is {computeSum arraySpan:N0}"
// Create an array from native memory.
let native = Marshal.AllocHGlobal 100
let nativeSpan = Span<byte>(native.ToPointer(), 100)
initializeSpan nativeSpan
printfn $"The sum is {computeSum nativeSpan:N0}"
Marshal.FreeHGlobal native
// Create a span on the stack.
let stackSpan = stackalloc 100
initializeSpan stackSpan
printfn $"The sum is {computeSum stackSpan:N0}"
// The example displays the following output:
// The sum is 4,950
// The sum is 4,950
// The sum is 4,950
スパン<T> と配列
配列をラップする場合は、「 Span<T>
スパン<T> とメモリ 」セクションの例のように、配列全体をラップできます。 スライスがサポートされているため、 Span<T>
配列内の連続する範囲を指すこともできます。
次の例では、10 要素ある整数配列の中間 5 つの要素のスライスを作成します。 コードがスライス内の各整数の値を 2 倍することに注意してください。 出力のとおり、スパンで加えられた変更は、配列の値に反映されます。
using System;
var array = new int[] { 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 };
var slice = new Span<int>(array, 2, 5);
for (int ctr = 0; ctr < slice.Length; ctr++)
slice[ctr] *= 2;
// Examine the original array values.
foreach (var value in array)
Console.Write($"{value} ");
Console.WriteLine();
// The example displays the following output:
// 2 4 12 16 20 24 28 16 18 20
module Program
open System
[<EntryPoint>]
let main _ =
let array = [| 2; 4; 6; 8; 10; 12; 14; 16; 18; 20 |]
let slice = Span<int>(array, 2, 5)
for i = 0 to slice.Length - 1 do
slice[i] <- slice[i] * 2
// Examine the original array values.
for value in array do
printf $"{value} "
printfn ""
0
// The example displays the following output:
// 2 4 12 16 20 24 28 16 18 20
スパン<T> とスライス
Span<T>
には、現在のスパンより、指定したインデックスから始まるスライスを形成するSliceメソッドの 2 つのオーバー ロードが含まれています。 これにより、Span<T>
のデータを、パフォーマンスの影響を最小限にしながら、データ処理パイプラインの一部で必要に応じて処理できる、一連の論理的なまとまりとして扱うことができます。 たとえば、最新のサーバー プロトコルは多くの場合、テキスト ベースであるため、文字列と部分文字列の操作は特に重要です。 Stringクラスの場合、部分文字列の抽出に使う主要なメソッドはSubstringです。 広範な文字列操作に依存するデータ パイプラインは、次のように、いくつかのパフォーマンスの低下を招きます。
部分文字列を保持する新しい文字列を作成します。
元の文字列から新しい文字列に文字のサブセットをコピーします。
次の例に示すように、この割り当てとコピー操作は、Span<T>
またはReadOnlySpan<T>いずれかを使用して削除できます。
using System;
class Program2
{
static void Run()
{
string contentLength = "Content-Length: 132";
var length = GetContentLength(contentLength.ToCharArray());
Console.WriteLine($"Content length: {length}");
}
private static int GetContentLength(ReadOnlySpan<char> span)
{
var slice = span.Slice(16);
return int.Parse(slice);
}
}
// Output:
// Content length: 132
module Program2
open System
let getContentLength (span: ReadOnlySpan<char>) =
let slice = span.Slice 16
Int32.Parse slice
let contentLength = "Content-Length: 132"
let length = getContentLength (contentLength.ToCharArray())
printfn $"Content length: {length}"
// Output:
// Content length: 132
コンストラクター
Span<T>(T) |
指定した参照の周囲に長さ 1 の新しい Span<T> を作成します。 |
Span<T>(T[]) |
指定された配列全体で新しい Span<T> オブジェクトを作成します。 |
Span<T>(T[], Int32, Int32) |
指定インデックスで始まる配列の指定要素数を含む新しい Span<T> オブジェクトを作成します。 |
Span<T>(Void*, Int32) |
指定したメモリ アドレスから始まる、指定した数の |
プロパティ
Empty |
空の Span<T> オブジェクトを返します。 |
IsEmpty |
現在の Span<T> が空かどうかを示す値を返します。 |
Item[Int32] |
0 から始まる指定したインデックス位置にある要素を取得します。 |
Length |
現在のスパンの長さを返します。 |
メソッド
Clear() |
この Span<T> オブジェクトの内容を消去します。 |
CopyTo(Span<T>) | |
Equals(Object) |
互換性のために残されています。
互換性のために残されています。
このメソッドを呼び出すことはできません。 |
Fill(T) |
このスパンの要素に指定の値を入力します。 |
GetEnumerator() |
この Span<T> の列挙子を返します。 |
GetHashCode() |
互換性のために残されています。
NotSupportedException をスローします。 |
GetPinnableReference() |
ピン留めに使用できる T 型のオブジェクトへの参照を返します。 このメソッドは.NET コンパイラをサポートすることを目的としており、ユーザー コードによって呼び出されるものではありません。 |
Slice(Int32) |
指定のインデックスで始まる現在のスパンからスライスを形成します。 |
Slice(Int32, Int32) |
指定インデックスから始まる現在のスパンからスライスを指定の長さで形成します。 |
ToArray() |
このスパンの内容を新しい配列にコピーします。 |
ToString() |
この Span<T> オブジェクトの文字列表現を返します。 |
TryCopyTo(Span<T>) |
コピー先 Span<T> に対して現在の Span<T> のコピーを試行し、コピー操作が成功したかどうかを示す値を返します。 |
演算子
Equality(Span<T>, Span<T>) |
2 つの Span<T> オブジェクトが等しいかどうかを示す値を返します。 |
Implicit(ArraySegment<T> to Span<T>) |
ArraySegment<T> から Span<T> への暗黙の型変換を定義します。 |
Implicit(Span<T> to ReadOnlySpan<T>) |
Span<T> から ReadOnlySpan<T> への暗黙の型変換を定義します。 |
Implicit(T[] to Span<T>) |
配列から Span<T> への暗黙の型変換を定義します。 |
Inequality(Span<T>, Span<T>) |
2 つの Span<T> オブジェクトが等しくないかどうかを示す値を返します。 |
拡張メソッド
ToImmutableArray<T>(Span<T>) |
スパンを変更できない配列に変換します。 |
BinarySearch<T>(Span<T>, IComparable<T>) |
指定した IComparable<T> ジェネリック インターフェイスを使用し、並べ替えられた Span<T> 全体の中から値を検索します。 |
BinarySearch<T,TComparer>(Span<T>, T, TComparer) |
指定した |
BinarySearch<T,TComparable>(Span<T>, TComparable) |
指定した |
CommonPrefixLength<T>(Span<T>, ReadOnlySpan<T>) |
と |
CommonPrefixLength<T>(Span<T>, ReadOnlySpan<T>, IEqualityComparer<T>) |
と |
Contains<T>(Span<T>, T) |
指定した値がスパンに存在するかどうかを示します。 値は IEquatable{T}.Equals(T) を使用して比較されます。 |
ContainsAny<T>(Span<T>, T, T) |
または |
ContainsAny<T>(Span<T>, T, T, T) |
、 |
ContainsAny<T>(Span<T>, SearchValues<T>) |
指定した |
ContainsAny<T>(Span<T>, ReadOnlySpan<T>) |
指定した |
ContainsAnyExcept<T>(Span<T>, T) |
指定した 以外の値を検索します |
ContainsAnyExcept<T>(Span<T>, T, T) |
または |
ContainsAnyExcept<T>(Span<T>, T, T, T) |
、 |
ContainsAnyExcept<T>(Span<T>, SearchValues<T>) |
指定した 以外の値を検索します |
ContainsAnyExcept<T>(Span<T>, ReadOnlySpan<T>) |
指定した 以外の値を検索します |
ContainsAnyExceptInRange<T>(Span<T>, T, T) |
と |
ContainsAnyInRange<T>(Span<T>, T, T) |
と |
Count<T>(Span<T>, T) |
で指定した |
Count<T>(Span<T>, ReadOnlySpan<T>) |
で指定した |
EndsWith<T>(Span<T>, ReadOnlySpan<T>) |
指定されたシーケンスがスパンの末尾にあるかどうかを判断します。 |
IndexOf<T>(Span<T>, T) |
指定した値を検索し、それが最初に見つかった位置のインデックスを返します。 値は IEquatable{T}.Equals(T) を使用して比較されます。 |
IndexOf<T>(Span<T>, ReadOnlySpan<T>) |
指定したシーケンスを検索し、それが最初に見つかった位置のインデックスを返します。 値は IEquatable{T}.Equals(T) を使用して比較されます。 |
IndexOfAny<T>(Span<T>, T, T) |
論理 OR 演算子を使用して IndexOf を数回呼び出すのと同様に、指定されたいずれかの値の最初のインデックスを検索します。 |
IndexOfAny<T>(Span<T>, T, T, T) |
論理 OR 演算子を使用して IndexOf を数回呼び出すのと同様に、指定されたいずれかの値の最初のインデックスを検索します。 |
IndexOfAny<T>(Span<T>, SearchValues<T>) |
指定した値の最初のインデックスを検索します。 |
IndexOfAny<T>(Span<T>, ReadOnlySpan<T>) |
論理 OR 演算子を使用して IndexOf を数回呼び出すのと同様に、指定されたいずれかの値の最初のインデックスを検索します。 |
IndexOfAnyExcept<T>(Span<T>, T) |
指定した 以外の値の最初のインデックスを検索します |
IndexOfAnyExcept<T>(Span<T>, T, T) |
指定した |
IndexOfAnyExcept<T>(Span<T>, T, T, T) |
指定した |
IndexOfAnyExcept<T>(Span<T>, SearchValues<T>) |
指定した 以外の値の最初のインデックスを検索します |
IndexOfAnyExcept<T>(Span<T>, ReadOnlySpan<T>) |
指定した 以外の値の最初のインデックスを検索します |
IndexOfAnyExceptInRange<T>(Span<T>, T, T) |
と の範囲 |
IndexOfAnyInRange<T>(Span<T>, T, T) |
と を含む範囲内 |
LastIndexOf<T>(Span<T>, T) |
指定した値を検索し、それが最後に見つかった位置のインデックスを返します。 値は IEquatable{T}.Equals(T) を使用して比較されます。 |
LastIndexOf<T>(Span<T>, ReadOnlySpan<T>) |
指定したシーケンスを検索し、それが最後に見つかった位置のインデックスを返します。 値は IEquatable{T}.Equals(T) を使用して比較されます。 |
LastIndexOfAny<T>(Span<T>, T, T) |
論理 OR 演算子で LastIndexOf を数回呼び出すのと同様に、指定された値のいずれかの最後のインデックスを検索します。 |
LastIndexOfAny<T>(Span<T>, T, T, T) |
論理 OR 演算子で LastIndexOf を数回呼び出すのと同様に、指定された値のいずれかの最後のインデックスを検索します。 |
LastIndexOfAny<T>(Span<T>, SearchValues<T>) |
指定した値の最後のインデックスを検索します。 |
LastIndexOfAny<T>(Span<T>, ReadOnlySpan<T>) |
論理 OR 演算子で LastIndexOf を数回呼び出すのと同様に、指定された値のいずれかの最後のインデックスを検索します。 |
LastIndexOfAnyExcept<T>(Span<T>, T) |
指定した 以外の値の最後のインデックスを検索します |
LastIndexOfAnyExcept<T>(Span<T>, T, T) |
指定した |
LastIndexOfAnyExcept<T>(Span<T>, T, T, T) |
指定した |
LastIndexOfAnyExcept<T>(Span<T>, SearchValues<T>) |
指定した 以外の値の最後のインデックスを検索します |
LastIndexOfAnyExcept<T>(Span<T>, ReadOnlySpan<T>) |
指定した 以外の値の最後のインデックスを検索します |
LastIndexOfAnyExceptInRange<T>(Span<T>, T, T) |
と の範囲 |
LastIndexOfAnyInRange<T>(Span<T>, T, T) |
と を含む範囲内 |
Overlaps<T>(Span<T>, ReadOnlySpan<T>) |
スパンと読み取り専用スパンがメモリ内で重なり合うかどうかを判断します。 |
Overlaps<T>(Span<T>, ReadOnlySpan<T>, Int32) |
スパンと読み取り専用スパンがメモリ内で重なり合うかどうかを判断し、要素のオフセットを出力します。 |
Replace<T>(Span<T>, T, T) |
出現するすべての |
Reverse<T>(Span<T>) |
スパン全体の要素のシーケンスを反転させます。 |
SequenceCompareTo<T>(Span<T>, ReadOnlySpan<T>) |
IComparable{T}.CompareTo(T) を使用して要素を比較することで、スパンと読み取り専用スパンの相対順序を決定します。 |
SequenceEqual<T>(Span<T>, ReadOnlySpan<T>) |
IEquatable{T}.Equals(T) を使用して要素を比較することで、スパンと読み取り専用スパンが等しいかどうかを判断します。 |
SequenceEqual<T>(Span<T>, ReadOnlySpan<T>, IEqualityComparer<T>) |
を使用して IEqualityComparer<T>要素を比較することで、2 つのシーケンスが等しいかどうかを判断します。 |
Sort<T>(Span<T>) |
の各要素の実装を使用して、IComparable<T>全体Span<T>の要素をSpan<T>並べ替えます。 |
Sort<T>(Span<T>, Comparison<T>) |
指定した Comparison<T> を使用して、Span<T> 全体内の要素を並べ替えます。 |
Sort<T,TComparer>(Span<T>, TComparer) |
|
Sort<TKey,TValue>(Span<TKey>, Span<TValue>) |
スパンのペア (一方がキーを格納し、他方がそれらに対応する項目を格納する) を、最初の Span<T> 内のキーに基づき、各キーによって実装された IComparable<T> を使用して並べ替えます。 |
Sort<TKey,TValue>(Span<TKey>, Span<TValue>, Comparison<TKey>) |
スパンのペア (一方がキーを格納し、他方がそれらに対応する項目を格納する) を、最初の Span<T> 内のキーに基づき、指定した比較を使用して並べ替えます。 |
Sort<TKey,TValue,TComparer>(Span<TKey>, Span<TValue>, TComparer) |
スパンのペア (一方がキーを格納し、他方がそれらに対応する項目を格納する) を、最初の Span<T> 内のキーに基づき、指定した比較子を使用して並べ替えます。 |
StartsWith<T>(Span<T>, ReadOnlySpan<T>) |
指定されたシーケンスがスパンの先頭にあるかどうかを判断します。 |
Trim<T>(Span<T>, T) |
指定された要素が先頭と末尾に現れる箇所をすべて、スパンから削除します。 |
Trim<T>(Span<T>, ReadOnlySpan<T>) |
読み取り専用スパンで指定された一連の要素が先頭と末尾に現れる箇所をすべて、スパンから削除します。 |
TrimEnd<T>(Span<T>, T) |
指定された要素が末尾に現れる箇所をすべて、スパンから削除します。 |
TrimEnd<T>(Span<T>, ReadOnlySpan<T>) |
読み取り専用スパンで指定された一連の要素が末尾に現れる箇所をすべて、スパンから削除します。 |
TrimStart<T>(Span<T>, T) |
指定した要素が先頭に現れる箇所をすべてスパンから削除します。 |
TrimStart<T>(Span<T>, ReadOnlySpan<T>) |
読み取り専用スパンで指定された一連の要素が先頭に現れる箇所をすべて、スパンから削除します。 |
適用対象
こちらもご覧ください
フィードバック
フィードバックの送信と表示