正規表現におけるコンパイルと再利用Compilation and Reuse in Regular Expressions

正規表現エンジンが式をどのようにコンパイルするか、および正規表現がどのようにキャッシュされるかを理解することで、正規表現を幅広く使用するアプリケーションのパフォーマンスを最適化できます。You can optimize the performance of applications that make extensive use of regular expressions by understanding how the regular expression engine compiles expressions and by understanding how regular expressions are cached. このトピックでは、コンパイルとキャッシュの両方について説明します。This topic discusses both compilation and caching.

コンパイルされた正規表現Compiled Regular Expressions

既定では、正規表現エンジンは、内部命令のシーケンス (Microsoft 中間言語 (MSIL) とは異なる高度なコード) に正規表現をコンパイルします。By default, the regular expression engine compiles a regular expression to a sequence of internal instructions (these are high-level codes that are different from Microsoft intermediate language, or MSIL). エンジンは、正規表現を実行するときに内部コードを解釈します。When the engine executes a regular expression, it interprets the internal codes.

RegexOptions.Compiled オプションを使用して Regex オブジェクトを構築した場合、このオブジェクトは、高度な正規表現の内部命令ではなく明示的な MSIL コードに正規表現をコンパイルします。If a Regex object is constructed with the RegexOptions.Compiled option, it compiles the regular expression to explicit MSIL code instead of high-level regular expression internal instructions. これにより、.NET の Just-In-Time (JIT) コンパイラは、式をネイティブのマシン コードに変換してパフォーマンスを高めることができます。This allows .NET's just-in-time (JIT) compiler to convert the expression to native machine code for higher performance. Regex オブジェクトの作成にかかるコストは高くなる場合がありますが、それとの照合の実行にかかるコストは大幅に小さくなる可能性があります。The cost of constructing the Regex object may be higher, but the cost of performing matches with it is likely to be much smaller.

事前にコンパイルされた正規表現を使用するという方法もあります。An alternative is to use precompiled regular expressions. CompileToAssembly メソッドを利用し、すべての式をコンパイルして再利用可能な DLL を作成できます。You can compile all of your expressions into a reusable DLL by using the CompileToAssembly method. これにより、コンパイルされた高速な正規表現を利用しながら、実行時にコンパイルする必要性を回避できます。This avoids the need to compile at run time while still benefiting from the speed of compiled regular expressions.

正規表現のキャッシュThe Regular Expressions Cache

パフォーマンスを高めるために、正規表現エンジンは、コンパイルされた正規表現のアプリケーション全体のキャッシュを保持します。To improve performance, the regular expression engine maintains an application-wide cache of compiled regular expressions. キャッシュは、静的メソッド呼び出しでのみ使用される正規表現パターンを格納しますThe cache stores regular expression patterns that are used only in static method calls. (インスタンス メソッドに渡される正規表現パターンはキャッシュされません)。これにより、式を使用するたびに高度なバイト コードに再解析する必要がなくなります。(Regular expression patterns supplied to instance methods are not cached.) This avoids the need to reparse an expression into high-level byte code each time it is used.

キャッシュされる正規表現の最大数は、static (Visual Basic では Shared) Regex.CacheSize プロパティの値によって決定されます。The maximum number of cached regular expressions is determined by the value of the static (Shared in Visual Basic) Regex.CacheSize property. 既定では、正規表現エンジンは最大 15 個のコンパイルされた正規表現をキャッシュします。By default, the regular expression engine caches up to 15 compiled regular expressions. コンパイルされた正規表現の数がキャッシュ サイズを超えた場合は、最近の使用頻度が最も低い正規表現が破棄され、新しい正規表現がキャッシュされます。If the number of compiled regular expressions exceeds the cache size, the least recently used regular expression is discarded and the new regular expression is cached.

アプリケーションでは、次の 2 つの方法のいずれかで正規表現を再利用できます。Your application can reuse regular expressions in one of the following two ways:

  • Regex オブジェクトの静的メソッドを使用して、正規表現を定義する。By using a static method of the Regex object to define the regular expression. 別の静的メソッド呼び出しで既に定義されている正規表現パターンを使用している場合、正規表現エンジンではキャッシュからのその取得が試みられます。If you're using a regular expression pattern that has already been defined by another static method call, the regular expression engine will try to retrieve it from the cache. キャッシュに使用できるものがない場合、エンジンによって正規表現がコンパイルされてキャッシュに追加されます。If it's not available in the cache, the engine will compile the regular expression and add it to the cache.

  • 既存の Regex オブジェクトの正規表現パターンが必要な間、このオブジェクトを再利用する。By reusing an existing Regex object as long as its regular expression pattern is needed.

オブジェクトのインスタンス化および正規表現のコンパイルのオーバーヘッドが原因となり、さまざまな Regex オブジェクトを作成してすぐに破棄するプロセスは非常にコストがかかります。Because of the overhead of object instantiation and regular expression compilation, creating and rapidly destroying numerous Regex objects is a very expensive process. 多数の異なる正規表現を使用するアプリケーションの場合は、静的 Regex メソッドの呼び出しを使用することで、および場合によっては正規表現キャッシュのサイズを大きくすることで、パフォーマンスを最適化できます。For applications that use a large number of different regular expressions, you can optimize performance by using calls to static Regex methods and possibly by increasing the size of the regular expression cache.

関連項目See also