1

文字列を持ってからこの文字列に対してサブ文字列を呼び出す方が速いのは何ですか?最初のサブ文字列は最初の文字列になり、すべての新しいサブ文字列は最初のサブ文字列内から最後まで小さな部分になりますか?または、StringBuilderを使用して、最初からどんどん切り取ってから、縮小する文字列から常にToStringを使用しますか?

このリンクは、新しいスレッドがStringBuilderにアクセスするか、返された文字列が現在割り当てられているスペースよりもはるかに小さい場合にのみ、StringBuilderToStringメソッドが新しいスペースを割り当てることを説明しています。これは、サブストリングを使用するよりも速く聞こえます。このロジックは、.NetFramework3.5までの実装内で確認できます。バージョン4.0では、FastAllocateStringがすぐに呼び出されます(String Substringの場合とほぼ同じです)。以前のフレームワークバージョンと同じロジックですが、現在は非表示になっていますか?

なぜそれが必要なのか:

編集:更新された説明:正規表現とコンテキストを指定した文字列とユーザーのセットがあります。コンテキストは、文字列の先頭と一致させようとするために現在どの正規表現が興味深いかを教えてくれます。一致が成功した後、文字列の開始は最後の一致が終了した場所の後になります。そして今、別の文脈があるかもしれません。さらに、前回の開始と一致した正規表現を知りたいです。これは複数回行われるため、パフォーマンスは可能な限り良好である必要があります。

(残りの)文字列全体の検索を回避するために、開始アンカー(^)を使用します。これにより、(開始が一致しないことがわかった後)できるだけ早く検索を中止できます。これを行うと、Matchメソッドの開始インデックスパラメーターを0以外では使用できないという問題があります。そうしないと、アンカーのおかげで一致が発生しなくなります。

だから私は今2つの可能性があると思います:

1)入力文字列に対して常にSubstringメソッドを使用し、現在の位置を保持してインデックスを作成します。

2)StringBuilderを使用し、一致が成功した場合は常に入力の開始を削除します。次に、ToStringメソッドを呼び出して、新しい開始が次の正規表現と一致するかどうかを確認します。

上記のアプローチの一方または両方のパフォーマンスは許容範囲内ですか、それともより高速な別の方法がありますか?

Edit2: StringBuilderとStringについて:ここで説明するように、StringBuilderの実装はすぐにスペースを割り当てますが、以前はStringBuilder文字列が変更されるまでこれは遅延していました(私の要件では常にそうでした)。したがって、SubstringとToStringはどちらも、KendallFreyの正規表現のみのソリューションと比較して非常に遅いと思います。

4

2 に答える 2

3

これを行う必要はありません。\G.NET正規表現エンジンには、アンカーを使用して、前回の一致の直後に文字列を一致させることができる機能が含まれています。

正規表現の例:

\Gcat

文字列の例:

catcatcatdogcat

一致:

(cat)(cat)(cat)dogcat

\G編集:正規表現では、複数の正規表現間のアンカー位置を思い出せないと思います。代わりに、Regex.Match(string, int)オーバーロードを使用して特定のポイントで文字列を開始し、\Gアンカーを使用して開始位置に一致させることができます。

于 2012-07-25T18:12:21.190 に答える
0

多くの文字列操作メソッドには、開始/終了または開始/長さのペアを持つバージョンがあります。

つまり、Regex.Matchを使用してサブ文字列を照合できます。これは、文字列を部分的に切り取ったり、センチネル文字を挿入したりするよりも高速である可能性があります。

public Match Match(string input, int beginning, int length)

注:パフォーマンスに関する質問と同様に、バリアントを試して、データを自分で測定する必要があります

于 2012-07-25T18:06:41.293 に答える