Производительность
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 сделает это за вас), чтобы кэши грамматик и тем использовались совместно при разных вызовах.