Contacter l'assistance

Nous répondons par e-mail, en général sous deux jours.

Pour prévenir les abus, Google reCAPTCHA vérifie cet envoi ; des données sont transmises à Google. Le script n'est chargé qu'à l'ouverture de ce formulaire.

← Tous les articles

Chaque requête charge tout lib/

La ligne 46 de l'unique fichier d'entrée de ce service :

foreach (glob(__DIR__ . '/lib/*.php') as $f) { require_once $f; }

Cela fait 65 fichiers et 1,5 mégaoctet, chargés à chaque requête. Une image de compteur, une page de statistiques, un 404 — tout pareil. Hier, cela s'est produit 20 734 fois.

26 familles de modèles — 715 Ko, une seule sert drapeaux 189 Ko · graphiques 158 Ko · tout le reste 470 Ko à froid, sans cache d'opcodes : 132 ms opcodes depuis le disque : 18,2 ms opcodes en mémoire partagée : 0,33 ms — le glob et 65 stat 65 fichiers, 1,5 Mo, 56 classes, à chaque requête

Le chiffre qui compte est le petit

Tout charger depuis zéro, avec le cache d'opcodes éteint, prend environ 132 millisecondes. C'est le chiffre qui ferait de ceci un scandale, et ce n'est pas le chiffre que paie le serveur.

Avec les opcodes déjà compilés et en mémoire partagée, il reste le listage du répertoire et un stat() par fichier, car la validation des horodatages est activée : 0,33 milliseconde. Au trafic d'hier, cela fait moins de sept secondes de travail sur toute la journée.

Entre les deux se trouve une troisième mesure, 18,2 millisecondes, avec un cache d'opcodes qui lit depuis le disque plutôt que la mémoire. C'est une borne supérieure et non le vrai chiffre — c'est ce qui arrive quand le cache existe mais est plus lent que le vrai. Il est rapporté parce que c'est le seul chiffre à chaud mesurable depuis la ligne de commande, et prétendre autrement serait l'erreur confortable.

Donc : cela ne coûte presque rien, et cela ne coûte presque rien entièrement grâce à autre chose. Coupez le cache d'opcodes et la même ligne coûte quatre cents fois plus. C'est une dépendance réelle, et il vaut mieux savoir qu'elle est là que la découvrir pendant une mise à jour.

Ce qu'il y a vraiment dans les 1,5 mégaoctet

Quarante-sept pour cent — 715 kilooctets répartis sur 26 fichiers — sont des familles de modèles de compteur. Dessiner une image de compteur en demande exactement une. Les 25 autres sont chargées, déclarées, et jamais touchées.

Ensuite : 189 kilooctets de données de drapeaux, utiles sur la page des pays ; 158 kilooctets de bibliothèque de graphiques, utile quand quelque chose dessine un graphique. Ni l'un ni l'autre n'intervient pour servir une image de compteur, qui est la requête à laquelle ce service répond plus qu'à toute autre.

Le coût visible en est la mémoire plutôt que le temps. Le pic par requête monte d'environ quatre mégaoctets et, contrairement aux opcodes — partagés entre tous les processus — cette part est payée par requête, en parallèle, par chaque travailleur à la fois.

Quelqu'un l'a déjà remarqué

Le glob est lib/*.php. Il ne descend pas, et deux répertoires se trouvent juste en dessous : lib/live/ avec 229 kilooctets et lib/recht/ avec 182 kilooctets. Quatre cents kilooctets qui étaient dans le chemin de chargement et n'y sont plus.

Ils ont été déplacés parce qu'ils sont gros et rarement nécessaires : les sections de statistiques et les textes juridiques. Être un répertoire plus bas, c'est tout le mécanisme. Pas de réglage, pas de chargeur différé, pas de table d'autochargement — un fichier est dans le glob ou il n'y est pas.

C'est une vraie correction et cela mérite d'être dit, car l'étape suivante évidente serait un autochargeur, et un autochargeur ici serait un grand changement pour un problème qu'un mkdir a déjà résolu deux fois.

Pourquoi cela reste

Un seul glob est la chose la plus simple qui puisse fonctionner, et à la mesure elle fonctionne : un tiers de milliseconde, sur un Raspberry Pi, sur le chemin qui doit être rapide. Le remplacer par des inclusions une par une signifie que chaque nouveau fichier a besoin d'une ligne quelque part, et la ligne oubliée produit une erreur fatale en production plutôt qu'un chargement un peu plus gros.

Ce qui manque, c'est d'écrire ce qui l'a rendu supportable dès le départ : quand un fichier de lib/ devient gros, il passe dans un sous-répertoire et est inclus là où il sert. C'est la règle que suivaient ces deux répertoires, et elle n'était écrite nulle part jusqu'ici.

La version générale est plus ennuyeuse que la mesure. « Tout charge tout » est en général la mauvaise forme, et il vaut la peine de savoir si cela vous coûte quelque chose avant de reconstruire. Ici cela coûte 0,33 milliseconde et quatre mégaoctets, et ce sont les quatre mégaoctets qu'il faut surveiller, car ils croissent avec la concurrence, pas les millisecondes.

Publicité