
# Продуктивність

shikiphp виконує справжню токенізацію TextMate на чистій PHP, тож варто чесно сказати, де він працює швидко, а де — ні.

## Чого очікувати

Очікуйте десятки й сотні мілісекунд на файл, а не мікросекунди. Токенізатор кешує скомпільовані правила й сканери, граматики завантажуються за потреби (якщо приклад не використовує вбудовану мову, її навіть не доведеться декодувати), а більшість шаблонів граматик проходить через нативний `preg_*` шляхом швидкого виконання PCRE з перевіркою еквівалентності; решту обробляє зіставлювач на чистій PHP (див.
[Архітектура](https://shikiphp.inline0.dev/uk/docs/architecture#the-scanner-and-its-pcre-fast-path)).

Це час виконання в прогрітому стані для одного виклику з репозиторного тесту продуктивності
(`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`](https://shikiphp.inline0.dev/uk/docs/options#tokenizemaxlinelength): для рядків заданої довжини або довших виводиться один звичайний токен — це захист від зловмисних однорядкових вхідних даних.

## Кешування в робочому середовищі

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

- Підсвічуйте код під час збирання статичних сайтів і документації.
- Кешуйте відображений HTML (за кодом і параметрами) для фрагментів, які ввели користувачі або які збережено в базі даних, і повторно використовуйте кеш, доки джерело не зміниться.

У межах процесу використовуйте один екземпляр підсвічувача (фасад `Shikiphp` робить це за вас), щоб кеші граматик і тем були спільними для всіх викликів.
