Wydajność
shikiphp przeprowadza rzeczywistą tokenizację TextMate w czystym PHP, dlatego warto uczciwie wyjaśnić, kiedy działa szybko, a kiedy nie.
Czego oczekiwać
Należy oczekiwać od kilkudziesięciu do kilkuset milisekund na plik, a nie mikrosekund. Tokenizator buforuje skompilowane reguły i skanery, gramatyki są ładowane na żądanie (próbka, która nie korzysta z osadzonego języka, nie wymaga jego dekodowania), a większość wzorców gramatyk przechodzi przez natywne preg_* w ścieżce przyspieszonej PCRE, której równoważność została zweryfikowana; pozostałe obsługuje dopasowywanie w czystym PHP (zobacz
Architektura).
To czasy dla rozgrzanego środowiska, przy pojedynczym wywołaniu, uzyskane w teście wydajnościowym repozytorium
(bench/bench.php, motyw github-dark) na jednej maszynie, dla plików korpusu mających
około 55 do 105 wierszy:
| Gramatyka | PHP 8.2 | PHP 8.4 |
|---|---|---|
| JSON, YAML | 30–65 ms | 25–45 ms |
| CSS, HTML | 100–120 ms | 80–100 ms |
| Python, Rust, Go, Bash, Markdown | 190–220 ms | 125–175 ms |
| PHP | około 290 ms | około 170 ms |
| TypeScript, TSX | 490–510 ms | 310–370 ms |
Pierwsze wywołanie danego języka w procesie wiąże się też z jednorazowym kosztem wczytania i kompilacji gramatyki: podczas tych samych uruchomień wynosił on od 50–70 ms dla JSON do nieco ponad sekundy dla Markdown. Koszt rośnie wraz ze złożonością gramatyki i rozmiarem danych wejściowych, a wyniki zależą od sprzętu, więc zmierz je we własnym środowisku: w klonie repozytorium uruchom composer install, a następnie composer bench.
Zabezpieczenia
Silnik wyrażeń regularnych obejmuje zapamiętywanie nieudanych dopasowań i ochronę przed ReDoS, dzięki czemu patologiczny wzorzec spowalnia działanie zamiast zawieszać program. Można też ograniczyć pracę wykonywaną dla każdego wiersza za pomocą tokenizeMaxLineLength. Wiersz o długości równej lub większej od określonej wartości otrzyma pojedynczy zwykły token — to zabezpieczenie przed złośliwymi danymi wejściowymi w jednym wierszu.
Buforowanie w środowisku produkcyjnym
Niezawodnym sposobem na usunięcie podświetlania ze ścieżki obsługi żądań jest nieuruchamianie go przy każdym żądaniu. Podświetlenie tego samego kodu przy tych samych opcjach zawsze daje ten sam wynik HTML, więc można je skutecznie buforować:
- Podświetlaj kod na etapie budowania witryn statycznych i dokumentacji.
- Buforuj wyrenderowany wynik HTML (klucz to kod i opcje) dla fragmentów podanych przez użytkownika lub przechowywanych w bazie danych i używaj go ponownie, dopóki źródło się nie zmieni.
W ramach jednego procesu używaj ponownie pojedynczego modułu podświetlania (fasada Shikiphp robi to za Ciebie), aby współdzielić pamięć podręczną gramatyk i motywów między wywołaniami.