コンテンツへスキップ

パフォーマンス

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ファサードが自動で処理します)。呼び出し間で文法とテーマのキャッシュが共有されます。