Blog
/
Opinions

Pourquoi Composer est lent

Publié le 4 février 2022 par Mathieu De Gracia
Couverture de l'article Pourquoi Composer est lent

Tous les développeurs PHP connaissent composer, développé début des années 2010 conjointement par Nils Adermann et Jordi Boggiano et remplaçant un PEAR désormais obsolète, l'outil est de nos jours tellement ancré dans nos habitudes que l'on peut difficilement imaginer travailler sans.

Mais après plus de 10 ans d'utilisation et des milliards de téléchargements de packages... pourquoi composer est aussi lent ?

Une histoire de validation

Contrairement à d'autres gestionnaires de dépendances tels que NPM, composer téléchargera toujours une seule version d'un même package même si plusieurs packages en on besoin.

Concrètement, cela signifie que si une application avec les packages A et B nécessite un package C, une seule version du package C répondant aux contraintes des packages A et B sera téléchargé.

1// Application
2"require": {
3 "packages/a": "1.0",
4 "packages/b": "1.0",
5},
6// packages/a
7"require": {
8 "packages/c": "^6.0|^7.0",
9},
10// packages/b
11"require": {
12 "packages/c": "6.2",
13},

Dans cette situation une version 6.2 du package/c sera téléchargé car elle répondra aux contraintes conjointes de pakages/a et pakages/b de notre application.

Si ces contraintes sont impossibles à satisfaire, composer lèvera une erreur "... not satisfy that requirement ..."

1// packages/a
2"require": {
3 "packages/c": "^6.0",
4},
5// packages/b
6"require": {
7 "packages/c": "^7.0",
8},

À chaque update, composer est donc obligé de récupérer une liste de toutes nos dépendances, de contacter les dépôts, de récupérer les versions disponibles et enfin essayer de résoudre quelles sont les packages qui répondront à l'ensemble des contraintes.

Notre exemple était assez simple, mais imaginez désormais un véritable projet avec plusieurs dizaines de dépendances ayant elles-mêmes des dizaines et des dizaines d'autres dépendances... et vous obtiendrez plusieurs millions de contraintes à vérifier.

Il est possible de visualiser ces règles à l'aide de la commande suivante :

1composer update --dry-run --profile -vv

On obtient ainsi quelques statistiques, par exemple pour un projet de moyenne envergure : 483 967 règles à valider.

1[556.7MiB/98.15s] Dependency resolution completed in 78.639 seconds
2[120.4MiB/98.25s] Analyzed 14 969 packages to resolve dependencies
3[120.4MiB/98.26s] Analyzed 483 967 rules to resolve dependencies

PHP étant un language de script sans multi threading, vous imaginez désormais sans mal comment un simple composer update peut emmagasiner à lui tout seul plusieurs GO de mémoire.

Mathieu De Gracia avatar
Mathieu De Gracia
Des fois, mon chat code à ma place 🐱

A lire

Autres articles de la même catégorie