Compilateur de squelettes, version 2

Archive historique

Ceci est une archive périmée mais qui reste intéressante, parfois autant pour l’article que les commentaires associés.

Compilation de squelettes minimisant les demandes au serveur SQL

Suite au travail posté ici le 5 septembre voici un nouveau compilateur des
squelettes SPIP vers PHP/MySQL. Cette nouvelle version :

-  reprend toutes les améliorations de la précédente (dont une partie a
déjà été intégrée dans la version CVS actuelle), savoir la correction de
bugs sur les séparateurs et les hiérarchies, et la réduction
de taille des boucles PHP, jusqu’à leur disparition dans certains cas ;

-  corrige un bug sur le calcul du champ TOTAL_BOUCLE qui référençait
parfois une autre boucle que celle souhaitée (bug visible dans le squelette
article de BIOSPIP) ;

-  élimine les appels systématiques au serveur SQL pour calculer le nombre de réponses sauf dans les rares cas où celui-ci est utile ;

-  ne demande au serveur SQL que les champs effectivement utilisés dans
la boucle SPIP.

-  diminue le nombre de résultats PHP intermédiaires en ne recopiant aucun des résultats du serveur SQL, et en construisant en une seule fois la chaîne HTML décrite par le corps d’une boucle SPIP.

La taille des squelettes standards en a été encore plus diminuée :

Nom Taille Spip 1.6 Taille finale
article-dist.php3 71140 30543
breve-dist.php3 45934 20170
forum-dist.php3 20518 8567
plan-dist.php3 23718 9202
resume-dist.php3 36398 14511
rubrique-dist.php3 48099 21099
sommaire-dist.php3 33499 19707

Mais c’est surtout la taille des processus qu’exécutent ces squelettes qui
devrait fortement diminuer, ainsi que leur temps d’exécution (les multiples
caches existant à tous les niveaux des matériels et programmes actuels
font qu’il est impossible d’avoir une mesure fiable des gains obtenus, mais
ils sont certains).

Sur le plan technique, cette nouvelle version du compilateur repose sur une
inversion des étapes de la compilation :
le code PHP correspondant aux boucles SPIP est calculé avant les codes SQL necéssaires à ce code PHP. Cette technique contre-intuitive (puisqu’à l’exécution le code SQL
sera exécuté avant le code PHP bien entendu) est ce qui permet de déterminer
les seuls champs à demander au serveur SQL.

Ce changement d’architecture a nécessité de réécrire le fichier
inc-calcul-squel qui a été éclaté en plusieurs fichiers, et d’intervenir sur trois autres (inc-champ-squel, inc-debug-squel, et inc-calcul) :

-  l’analyse des paramètres est découpée en deux : la requête SQL qu’ils décrivent n’est produite quà la fin, tandis qu’une analyse syntaxique se contente
d’écrire dans de nouveaux champs de la structure $boucles (qui se rapproche
d’un arbre de syntaxe abstraite) et de
dénoncer d’éventuelles erreurs (elles sont d’ailleurs mieux détectées, et en prime il y a maintenant la possibilité d’avoir des accolades dans un paramètre de type séparateur, i.e. dans des guillemets) ;
le reste de l’analyse syntaxique a peu changé (fichier inc-parse-squel) ;

-  la production de la requete s’effectue par deux fonctions (non plus trois),
la première à partir des paramètres, la deuxième à partir du type de la boucle,
(fichier inc-reqsql-squel) ;

-  $tables_code_contexte qui indiquaient les champs SQL à recopier dans le tableau $contexte (qui lui même était recopié ensuite dans l’espace GLOBAL) a été remplacée par $contextes qui permet de retrouver à quel endroit de la pile figure l’orginal d’un champ SQL (fichier inc-champ-squel) ;

-  le calcul des champs a peu changé dans son architecture (aiguillage sur une
soixantaine de cas) mais le code retourné référence systématiquement la pile,
et surtout mémorise dans la structure globale $boucles que ce champ devra être demandé au serveur SQL (fichier inc-index-squel).

-  le calcul des textes (inclusion du HTML des squelettes) n’a pas changé
(fichier inc-texte-squel)

-  la pile des objets InstanceBoucle a été remplacée par 2 piles, l’une formée
de résultats des requêtes SQL (c’est donc un tableau à 2 entrées) et l’autre
contenant seulement le nombre de ces résultats pour au plus chaque requête (utile
seulement à TOTAL_BOUCLE) : comme tous les autres champs de InstanceBoucle
n’étaient nécessaires qu’à la compilation du squelette, pas à son exécution,
cet objet a totalement disparu. On ne verra la valeur de certains d’entre eux qu’en cas d’erreur (fichier inc-debug-squel) ;

-  Les traductions sont donc produites en 2 temps (tout le PHP puis tout le SQL, les boucles les plus internes d’abord). Quand le
code calculant les champs a toujours retourné des expressions (i.e. sans aucune affectation préalable de variables auxiliaires) , le corps des boucles est une unique (et souvent gigantesque) concaténation (usage de «  ? : » plutot que « if » pour maximiser cette situation). Les variables auxiliaires sont réduites au minimum, savoir la profondeur d’emboitement des boucles SPIP (fichier inc-calcul-squel) ;

-  Enfin, le fichier inc-calcul a été légèrement modifié (élimination de la
fonction transformer_lien devenue si petite qu’elle a été réintégrée dans
l’aiguillage sur champs, et à l’inverse introduction de fonctions trop grosses
pour rester dans celui-ci).

Ce compilateur a été testé sur les squelettes standards ci-dessus et quelques uns de BioSPIP avec des résultats à première vue satisfaisants. Des bugs ne sont néanmoins
pas exclure. Je redoute surtout des incompatiblités avec les licences non
documentées mais exploitées plus ou moins consciemment par les utilisateurs.

En particulier, on pouvait accéder à des champs SQL non documentés, ce qui est plus difficile avec cette version. Il me semblerait
rationnel (mais c’est à discuter) d’officialiser que tout champ SQL est
un champ SPIP, ce qui reviendrait à identifier le tableau $contextes
évoqué ci-dessus avec les données de création des tables SQL figurant dans
inc_base.

Tout commentaire est évidemment le bienvenu.

Discussion

Aucune discussion

Ajouter un commentaire

Avant de faire part d’un problème sur un plugin X, merci de lire ce qui suit :

  • Désactiver tous les plugins que vous ne voulez pas tester afin de vous assurer que le bug vient bien du plugin X. Cela vous évitera d’écrire sur le forum d’une contribution qui n’est finalement pas en cause.
  • Cherchez et notez les numéros de version de tout ce qui est en place au moment du test :
    • version de SPIP, en bas de la partie privée
    • version du plugin testé et des éventuels plugins nécessités
    • version de PHP (exec=info en partie privée)
    • version de MySQL / SQLite
  • Si votre problème concerne la partie publique de votre site, donnez une URL où le bug est visible, pour que les gens puissent voir par eux-mêmes.
  • En cas de page blanche, merci d’activer l’affichage des erreurs, et d’indiquer ensuite l’erreur qui apparaît.

Merci d’avance pour les personnes qui vous aideront !

Par ailleurs, n’oubliez pas que les contributeurs et contributrices ont une vie en dehors de SPIP.

Qui êtes-vous ?
[Se connecter]

Pour afficher votre trombine avec votre message, enregistrez-la d’abord sur gravatar.com (gratuit et indolore) et n’oubliez pas d’indiquer votre adresse e-mail ici.

Ajoutez votre commentaire ici

Ce champ accepte les raccourcis SPIP {{gras}} {italique} -*liste [texte->url] <quote> <code> et le code HTML <q> <del> <ins>. Pour créer des paragraphes, laissez simplement des lignes vides.

Ajouter un document

Suivre les commentaires : RSS 2.0 | Atom