正規表現におけるコンパイルと再利用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.

ただし、生成された MSIL をアンロードすることはできません。However, generated MSIL cannot be unloaded. コードをアンロードする唯一の方法は、アプリケーション ドメイン全体をアンロードする (つまり、アプリケーションのすべてのコードをアンロードする) ことです。The only way to unload code is to unload an entire application domain (that is, to unload all of your application's code.). 実際には、RegexOptions.Compiled オプションを使用して正規表現をコンパイルすると、Regex オブジェクト (それ自体がガベージ コレクションに解放される) によって正規表現が作成された場合でも、.NET は、コンパイルされた式で使用されるリソースを解放することはありません。Effectively, once a regular expression is compiled with the RegexOptions.Compiled option, never releases the resources used by the compiled expression, even if the regular expression was created by a Regex object that is itself released to garbage collection.

リソースを過剰に消費することがないよう、RegexOptions.Compiled オプションを使用してコンパイルするさまざまな正規表現の数を慎重に制限する必要があります。You must be careful to limit the number of different regular expressions you compile with the RegexOptions.Compiled option to avoid consuming too many resources. アプリケーションで多数または無制限の数の正規表現を使用しなければならない場合は、各式をコンパイルするのではなく、解釈する必要があります。If an application must use a large or unbounded number of regular expressions, each expression should be interpreted, not compiled. ただし、少数の正規表現が繰り返し使用される場合は、パフォーマンスを高めるために RegexOptions.Compiled を使用してコンパイルする必要があります。However, if a small number of regular expressions are used repeatedly, they should be compiled with RegexOptions.Compiled for better performance. 事前にコンパイルされた正規表現を使用するという方法もあります。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 runtime 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 take advantage of precompiled 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 are using a regular expression pattern that has already been defined in another static method call, the regular expression engine will retrieve it from the cache. そうでない場合、エンジンは正規表現をコンパイルしてキャッシュに追加します。If not, 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