Performance¶
Ce qui coûte du temps et de la mémoire dans ddi-l, avec des mesures et les réglages qui les modifient.
Temps indicatifs¶
Une étude de 5 000 variables (1,4 Mio de XML), Python 3.11 sur un seul cœur, médiane de plusieurs exécutions. Lisez ces chiffres comme des proportions, pas comme des garanties.
| Opération | Moteur lxml | Moteur stdlib |
|---|---|---|
read_ddi(data) |
0,02 s | 0,18 s |
write_ddi(document) |
0,06 s | 0,35 s |
Document.to_xml() |
0,6 s | 0,3 s |
lint_source(data) |
0,4 s | 0,2 s |
validate_source(data) (schéma seul) |
0,05 s | 1,4 s |
Document.validate() |
0,6 s | 3,5 s |
import ddi_l |
0,03 s | 0,03 s |
ddi --help |
0,08 s | 0,08 s |
Lorsque lxml est installé, un document est d'abord vérifié par le validateur C
de libxml2, qui confirme un document valide en quelques millisecondes.
xmlschema ne s'exécute que si cette
vérification échoue, pour produire le détail des anomalies : les erreurs
signalées sont donc les mêmes sur les deux moteurs. Sans lxml, toute
validation passe par xmlschema, écrit en Python pur, qui domine les temps
ci-dessus. schema_loader.set_validation_backend("python") désactive la
vérification libxml2.
À quoi s'attendre¶
- Les schémas sont chargés une fois par version. libxml2 compile les XSD
d'une version en 0,1 s environ. xmlschema demande environ 2 s et 20 à 25 Mio,
et n'est chargé qu'en cas de besoin ; les validations suivantes dans le même
processus réutilisent les deux.
ddi servecharge la version par défaut au démarrage. - La lecture est légère ; l'index des modèles est paresseux.
read_ddianalyse le XML et s'arrête là. L'index de résolution est construit au premier usage deDDIDocument.resolver, ou d'emblée avecbuild_index=True. Documentsérialise à la demande.to_xml(),save()etvalidate()réécrivent le modèle en XML à chaque appel. Regroupez vos modifications et sérialisez une seule fois.- Les références sont vérifiées par
save()seulement. Les références orphelines sont signalées par un uniqueDDIReferenceWarningà l'enregistrement.
Documents volumineux¶
Parcourez le document en flux plutôt que de charger tout l'arbre :
import ddi_l as ddi
for variable in ddi.iter_variables("large-study.xml"):
print(variable.identifier)
iter_variables et iter_questions libèrent chaque élément dès qu'il est
converti en objet ; la mémoire reste de l'ordre d'un seul élément (environ
190 Kio au maximum pour l'étude de 5 000 variables ci-dessus). iterparse_ddi
diffuse n'importe quel type maintenable ; ne demandez que les types utiles, car
un élément est conservé jusqu'à ce que l'élément demandé le plus englobant soit
construit.
API HTTP¶
ddi serve traite au plus --max-jobs documents à la fois (par défaut : le
nombre de processeurs) et répond 503 avec Retry-After au-delà. La
validation détient le GIL : plus de tâches simultanées que de cœurs ajoute de
la mémoire, pas du débit. Pour monter en charge, lancez plusieurs processus
derrière un répartiteur de charge.
Mesurer¶
Le dossier benchmarks/ du dépôt contient des scripts reproductibles :