Перейти к содержимому

Производительность

shikiphp выполняет полноценную токенизацию TextMate на чистом PHP, поэтому важно понимать, где он работает быстро, а где медленно.

Чего ожидать

Ожидайте десятков или сотен миллисекунд на файл, а не микросекунд. Токенизатор кэширует скомпилированные правила и сканеры, грамматики загружаются по запросу (если в образце не встречается встроенный язык, тратить время на его декодирование не придётся), а большинство шаблонов грамматик обрабатывается нативным preg_* по ускоренному пути PCRE, проверенному на эквивалентность; остальные обрабатывает сопоставитель на чистом PHP (см. раздел Архитектура).

Это результаты одного запуска с прогретым кэшем из теста производительности репозитория (bench/bench.php, тема github-dark), выполненного на одной машине на файлах корпуса примерно от 55 до 105 строк:

Грамматика PHP 8.2 PHP 8.4
JSON, YAML 30–65 мс 25–45 мс
CSS, HTML 100–120 мс 80–100 мс
Python, Rust, Go, Bash, Markdown 190–220 мс 125–175 мс
PHP около 290 мс около 170 мс
TypeScript, TSX 490–510 мс 310–370 мс

Первый вызов языка в процессе также требует однократной загрузки и компиляции грамматики: в тех же запусках это занимало от 50–70 мс для JSON до чуть больше секунды для Markdown. Затраты растут с усложнением грамматики и увеличением размера входных данных; результаты зависят от оборудования, поэтому измерьте их у себя: клонируйте репозиторий, выполните composer install, а затем composer bench.

Ограничения для защиты

Регулярный движок включает запоминание ошибок и защиту от ReDoS, поэтому патологический шаблон замедляет работу, а не вызывает зависание. Также можно ограничить обработку каждой строки с помощью tokenizeMaxLineLength: строки заданной длины и больше будут выводиться одним обычным токеном — это защита от вредоносных чрезмерно длинных строк.

Кэширование в рабочей среде

Надёжный способ убрать подсветку из пути обработки запроса — не запускать её при каждом запросе. Подсветка одного и того же кода с одинаковыми параметрами всегда даёт один и тот же HTML, поэтому результат отлично кэшируется:

  • Выполняйте подсветку во время сборки статических сайтов и документации.
  • Кэшируйте отрисованный HTML (по ключу из кода и параметров) для фрагментов, предоставленных пользователями или сохранённых в базе данных, и используйте его повторно, пока исходный код не изменится.

В рамках одного процесса используйте повторно один экземпляр подсветчика (фасад Shikiphp сделает это за вас), чтобы кэши грамматик и тем использовались совместно при разных вызовах.