Поделиться через


Компиляция и многократное использование

Производительность приложений, активно использующих регулярные выражения можно оптимизировать, если понимать, каким образом обработчик регулярных выражений компилирует выражения и каким образом кэшируются регулярные выражения. В этом разделе описаны и компиляция, и кэширование.

Скомпилированные регулярные выражения

По умолчанию обработчик регулярных выражений компилирует регулярные выражения в последовательность внутренних инструкций (это коды высокого уровня, которые отличаются от языка MSIL). Когда обработчик выполняет регулярное выражение, он преобразовывает внутренние коды.

Если объект Regex создается с параметром RegexOptions.Compiled, то регулярное выражение явно компилируется в язык MSIL вместо внутренних инструкций высокого уровня. Это позволяет JIT-компилятору платформы .NET Framework преобразовывать выражение в изначальный машинный код данного объекта для повышения производительности.

Однако созданный язык MSIL выгрузить невозможно. Выгрузить код можно, только выгрузив весь домен приложения (т.е. выгрузив весь код приложения). Фактически если регулярное выражение компилируется с параметром RegexOptions.Compiled, то платформа .NET Framework никогда не высвобождает ресурсы, использованные скомпилированным выражением, даже если регулярное выражение было создано объектом Regex, который сам готов для сборки мусора.

Необходимо соблюдать осторожность и ограничить число различных регулярных выражений, компилируемых с параметром RegexOptions.Compiled, чтобы избежать потребления слишком большого количества ресурсов. Если в приложении необходимо использовать большое или неограниченное число регулярных выражений, то необходимо их преобразовывать, а не компилировать. Если же нужно многократно использовать небольшое число регулярных выражений, то их следует компилировать с параметром RegexOptions.Compiled для повышения производительности. Альтернативой является предварительная компиляция регулярных выражений. Можно скомпилировать все выражения в многократно используемую библиотеку DLL с помощью метода CompileToAssembly. Это устранит необходимость компиляции в режиме выполнения и сохранит скорость как преимущество скомпилированных регулярных выражений.

Кэш регулярных выражений

Для повышения производительности обработчик регулярных выражений поддерживает кэш скомпилированных регулярных выражений на уровне приложения. Кэш хранит шаблоны регулярных выражений, которые используются только при вызове статических методов (шаблоны регулярных выражений, предоставляемые методами экземпляра, не кэшируются). Это устраняет потребность в повторном разборе выражения в байт-код высокого уровня при каждом его использовании.

Максимальное число кэшированных регулярных выражений определяется значением static (Shared в Visual Basic) свойства Regex.CacheSize. По умолчанию обработчик регулярных выражений кэширует до 15 скомпилированных регулярных выражений. Если число скомпилированных регулярных выражений превышает размер кэша, то из него удаляется наиболее давнее по использованию регулярное выражение и кэшируется новое регулярное выражение.

Важное примечаниеВажно

Принцип кэширования регулярных выражений в .NET Framework версии 2.0 значительно отличается от принципов, применявшихся в версиях 1.0 и 1.1.В .NET Framework версий 1.0 и 1.1 кэшировались все регулярные выражения, вызываемые как статическими методами, так и методами экземпляров.Кэш автоматически расширялся для хранения новых регулярных выражений.В платформе .NET Framework 2.0 кэшируются только регулярные выражения, используемые в вызовах статических методов.По умолчанию кэшируются последние 15 регулярных выражений, хотя размер кэша может быть задан значением свойства CacheSize.

Приложение может воспользоваться преимуществом заранее скомпилированных регулярных выражений одним из следующих двух способов:

  • Используя статический метод объекта Regex для определения регулярного выражения. Если используется шаблон регулярного выражения, который уже был определен при вызове другого статического метода, то обработчик регулярных выражений будет извлекать его из кэша. Если нет, то обработчик скомпилирует регулярное выражение и добавит его в кэш.

  • Путем многократного использования существующих объектов Regex до тех пор, пока необходим шаблон регулярного выражения.

Из-за высоких издержек при создании объектов и компиляции регулярных выражений создание и быстрое уничтожение многочисленных объектов Regex представляет собой очень ресурсоемкий процесс. Для приложений, использующих большое количество различных регулярных выражений, производительность можно оптимизировать с помощью вызова статических методов Regex и, возможно, путем увеличения размера кэша регулярных выражений.

См. также

Основные понятия

Регулярные выражения в .NET Framework