Start Debugging

.NET 10 パフォーマンス: SearchValues

.NET 10 で SearchValues を使い、高性能なマルチ文字列検索を実現します。foreach ループを Aho-Corasick および Teddy アルゴリズムによる SIMD 加速のマッチングに置き換えます。

.NET 8 で Microsoft は SearchValues<T> を導入しました。これは span 内の値の 集合 (バイトや char など) の検索を最適化する特殊な型です。検索をベクトル化することで、IndexOfAny よりも大幅に高速化されました。

.NET 10 では、この機能が文字列にまで拡張されました。SearchValues<string> を使うと、複数のサブ文字列を同時に、驚くべきパフォーマンスで検索できます。

ユースケース: パースとフィルタリング

特定の禁止ワードやトークンのリストにテキストが該当するかを確認する必要があるパーサーやサニタイザーを書いている状況を想像してください。

従来の方法 (遅い)

private static readonly string[] Forbidden = { "drop", "delete", "truncate" };

public bool ContainsSqlInjection(ReadOnlySpan<char> input)
{
    foreach (var word in Forbidden)
    {
        if (input.Contains(word, StringComparison.OrdinalIgnoreCase))
            return true;
    }
    return false;
}

これは O(N * M) です (N は入力の長さ、M は単語数)。文字列を繰り返しスキャンすることになります。

新しい方法: SearchValues

.NET 10 では、検索戦略を事前に計算できます。

using System.Buffers;

// 1. Create the optimized searcher (do this once, statically)
private static readonly SearchValues<string> SqlTokens = 
    SearchValues.Create(["drop", "delete", "truncate"], StringComparison.OrdinalIgnoreCase);

public bool ContainsSqlInjection(ReadOnlySpan<char> input)
{
    // 2. Search for ANY of them in one pass
    return input.ContainsAny(SqlTokens);
}

パフォーマンスへの影響

内部的に、SearchValues.Create はパターンを解析します。

10〜20 個のキーワードの集合に対しては、SearchValues はループや Regex に比べて 50 倍高速 になることがあります。

位置の特定

ブール値のチェックだけに限定されません。マッチが どこで 発生したかを見つけることもできます。

int index = input.IndexOfAny(SqlTokens);
if (index >= 0)
{
    Console.WriteLine($"Found distinct token at index {index}");
}

まとめ

.NET 10 の SearchValues<string> は、外部ライブラリに頼ることなく、高性能なテキスト検索を広く利用可能にします。テキスト処理、ログ解析、セキュリティフィルタリングなどを行っているなら、foreach ループを今すぐ SearchValues に置き換えましょう。

Comments

Sign in with GitHub to comment. Reactions and replies thread back to the comments repo.

< 戻る