パフォーマンス
shikiphpは純粋なPHPでTextMateのトークン化を実行します。得意な処理とそうでない処理を正直に説明します。
期待できること
ファイルごとに数十〜数百ミリ秒かかると考えてください。マイクロ秒単位ではありません。トークナイザーはコンパイル済みルールとスキャナーをキャッシュし、文法は遅延読み込みされます(埋め込み言語に触れないサンプルでは、その文法のデコードは発生しません)。多くの文法パターンは、同等性を検証したPCRE高速パスでネイティブpreg_*を通して実行され、残りは純粋なPHPマッチャーが処理します(アーキテクチャを参照)。
以下は、リポジトリのベンチマーク(bench/bench.php、テーマgithub-dark)で、約55〜105行のコーパスファイルを1台のマシンで処理した際の、ウォーム状態での単一呼び出しの時間です:
| 文法 | 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 | 約290 ms | 約170 ms |
| TypeScript、TSX | 490–510 ms | 310–370 ms |
プロセス内である言語を初めて処理する際は、文法の読み込みとコンパイルに一度だけ時間がかかります。同じ実行ではJSONの50〜70 msから、Markdownの1秒強まで幅がありました。コストは文法の複雑さと入力サイズに応じて変わり、ハードウェアによって数値も異なるため、手元の環境で計測してください。リポジトリをクローンして、composer install、続けてcomposer benchを実行します。
安全対策
正規表現エンジンには失敗のメモ化とReDoS対策が組み込まれており、極端なパターンでも処理が停止せず、性能が低下するだけです。tokenizeMaxLineLengthを使って行ごとの処理量を制限することもできます。指定した長さ以上の行は単一のプレーンなトークンとして出力され、悪意のある極端な単一行入力への対策になります。
本番環境でのキャッシュ
リクエスト処理で強調表示を実行しないための確実な方法は、毎回のリクエストで実行しないことです。同じオプションで同じコードを強調表示すれば、常に同じHTMLが生成されるため、完全にキャッシュできます:
- 静的サイトやドキュメントでは、ビルド時に強調表示します。
- ユーザー入力やデータベースに保存されたコード断片は、レンダリング済みのHTMLを(コードとオプションをキーにして)キャッシュし、ソースが変更されるまで再利用します。
プロセス内では、単一のハイライターを再利用してください(Shikiphpファサードが自動で処理します)。呼び出し間で文法とテーマのキャッシュが共有されます。