参考
この記事は、以下の動画を参考にしています。詳しくは、動画をご覧ください。
また、リファレンスも参考にしてください。
SearchValue<T>
- コレクションを引数にして、インスタンスを生成する
- インスタンスに対して
Containsメソッドを呼び、引数にした値が含まれているかどうかを戻す - .NET 8では、コレクションのデータ型は
charまたはbyteのみ - .NET 9では、加えて
stringも可能 - どのように
stringを比較するかは、インスタンスを生成するときに、StringComparisonを渡して、あらかじめ決める。Containsを呼ぶときにはStringComparisonを変更できない
訂正(追記)
参考にした動画に、訂正が入りました。
この記事も、訂正させていただきます。
Containsメソッドが本題ではない
SearchValues<T>.Containsメソッドは、SearchValues<T>を単にHashSet<T>として使っているだけである。実際にパフォーマンスは同等である。
長大な文字列から部分文字列を探す
長いstringに、特定の単語が含まれているかを調べたいとする。
string.Containsメソッドを使うと、次のようになる。
string longText = new HttpClient()
.GetStringAsync("https://www.gutenberg.org/cache/epub/100/pg100.txt")
.GetAwaiter()
.GetResult();
var targetWords = ["target", "words"];
var found = targetWords.Any(x => longText.Contains(x, StringComparison.OrdinalIgnoreCase);
// foundがtrueなら、targetWordsのいずれかを見つけた
SearchValues<string>を引数にするContainsAny拡張メソッドを使うと、以下のように記述できる。
ReadOnlySpan<char> longText = new HttpClient()
.GetStringAsync("https://www.gutenberg.org/cache/epub/100/pg100.txt")
.GetAwaiter()
.GetResult();
var targetWords = SearchValues.Create(["target", "words"],
StringComparison.OrdinalIgnoreCase);
var found = longText.ContainsAny(targetWords);
// foundがtrueなら、targetWordsのいずれかを見つけた
手元の実行環境では、後者は前者に比べて約半分の実行時間になった。
文字列に対してSearchValues<string>を引数にして呼び出せる拡張メソッド
以下の拡張メソッドが、System.MemoryExtensionsクラスで定義されている。(.NET 9 Preview 2時点)
ContainsAnyIndexOfAny
いずれのメソッドも、第1引数はSpan<char>またはReadOnlySpan<char>、第2引数はSearchValue<string>である。