Przejdź do treści

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.