Aller au contenu

Performances

shikiphp effectue une véritable tokenisation TextMate en pur PHP ; il est donc utile de préciser dans quels cas il est rapide et dans quels cas il ne l'est pas.

À quoi s'attendre

Prévoyez des dizaines à des centaines de millisecondes par fichier, et non des microsecondes. Le tokenizer met en cache les règles et scanners compilés, les grammaires sont chargées à la demande (un exemple qui n'utilise jamais de langage intégré n'a pas à le décoder), et la plupart des motifs des grammaires passent par preg_* natif, avec un chemin rapide PCRE soumis à une vérification d'équivalence ; le moteur pur PHP gère le reste (voir Architecture).

Voici des temps à chaud pour un appel unique, issus du benchmark du dépôt (bench/bench.php, thème github-dark), mesurés sur une machine avec des fichiers de corpus d'environ 55 à 105 lignes :

Grammaire 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 environ 290 ms environ 170 ms
TypeScript, TSX 490–510 ms 310–370 ms

Le premier appel à un langage dans un processus inclut aussi le chargement et la compilation de la grammaire, qui n'ont lieu qu'une fois : lors des mêmes exécutions, le délai allait de 50–70 ms pour JSON à un peu plus d'une seconde pour Markdown. Le coût dépend de la complexité de la grammaire et de la taille de l'entrée. Les chiffres varient selon le matériel : faites vos propres mesures en clonant le dépôt, puis en exécutant composer install et composer bench.

Protections de sécurité

Le moteur d'expressions régulières intègre la mémorisation des échecs et une protection contre ReDoS, afin qu'un motif problématique ralentisse le traitement au lieu de le bloquer. Vous pouvez aussi limiter le traitement par ligne avec tokenizeMaxLineLength : toute ligne dont la longueur atteint ou dépasse le seuil donné génère un seul jeton brut. Cela protège contre les entrées malveillantes sur une seule ligne.

Mise en cache en production

Pour éviter que la coloration syntaxique ne ralentisse vos requêtes, le plus sûr est de ne pas l'exécuter à chaque requête. La coloration du même code avec les mêmes options produit toujours le même HTML ; la mise en cache est donc très efficace :

  • Effectuez la coloration à la compilation pour les sites statiques et la documentation.
  • Mettez en cache le HTML généré (avec le code et les options comme clé) pour les extraits fournis par les utilisateurs ou stockés en base de données, et réutilisez-le jusqu'à ce que la source change.

Dans un processus, réutilisez un seul surligneur syntaxique (la façade Shikiphp le fait pour vous) afin de partager les caches des grammaires et des thèmes entre les appels.