mardi 28 juin 2016

Benchmarks Symfony

Symfony n'est pas connu pour être rapide (et c'est pas forcément là son but non plus).
Voilà quelques informations sur les différentes versions, du répertoire vendor/symfony, récupérées via AlDanial/cloc :

2.3.42 2.4.10 2.5.12 2.6.13 2.7.14 2.8.7 3.0.7 3.1.1
Fichiers 4 034 3 451 4 578 4 798 4 835 4 966 4 520 4 684
Lignes 561 903 344 694 602 693 632 603 654 992 675 141 615 327 629 976

Informations sur le nombre de fichiers, classes et interfaces inclus pour arriver au code d'une action de Controller (chiffre de gauche), puis à la toute fin du fichier app.php (chiffre de droite) :

2.3.42 2.4.10 2.5.12 2.6.13 2.7.14 2.8.7 3.0.7 3.1.1
Fichiers 86-152 81-160 91-162 101-173 107-180 119-183 114-210 122-218
Classes 294-341 294-351 306-356 317-369 313-365 315-361 311-371 321-381
Interfaces 74-93 77-99 77-98 81-101 82-103 87-105 86-115 93-122

En conclusion :
  • Pas loin de 59 000 lignes de code supprimées entre la 2.8 et la 3.0 (la 3.0 est la copie de la 2.8, avec toutes le code déprécié en moins)
  • Il faut tout de même 218 fichiers, 381 classes et 122 interfaces pour afficher un Hello World en 3.1
  • La 3.1 est 28% plus lente que la 2.8, ce qui est difficilement compréhensible

jeudi 9 juin 2016

Passer de Symfony 2.8 à Symfony 3.1

Etant sur un projet qui a débuté en Symfony 2.6, j'ai du effectuer les migrations vers la 2.7, puis la 2.8.
Concrètement, à part un problème en 2.8.5 sur le NumberType qui retournait un int ou un float, et qui s'est mit à retourner uniquement des float (même si on a saisi 1 par exemple, voir le commit), tout s'est bien passé.

Par contre, et même en faisant très attention à ne pas trop avoir de deprecated dans notre code, et sachant que Symfony 2.8 lui-même générait des centaines de deprecated, le passage à la 3.1 ne s'est pas fait sans mal ... Déjà à cause des bundles utilisés. Il a fallu attendre quelques mois pour que les dépendances fonctionnent (FOSUserBundle par exemple), et certaines ne seront jamais mis à jour (knplabs/doctrine-behaviors).
Voici une liste de ce qui m'a posé soucis, et comment je l'ai corrigé :
  • $validator->validate($value, $constraints = null, $groups = null) : l'ordre des paramètre a changé. Avant, on pouvait passer $groups en 2ème, ou en 3ème, au choix. Depuis la 3.0, $groups est forcément le 3ème paramètre.
  • Knp\DoctrineBehaviors\ORM\Blameable\UserCallable utilisait security.context, qui n'existe plus, au profit de security.token_storage. Comme KNP s'occupe très peu de la migration vers Symfony 3, j'ai du changer la configuration knp.doctrine_behaviors.blameable_subscriber.user_callable.class, pour la faire pointer sur une classe de mon projet, qui utilise le nouveau service.
  • ContainerInterface::isScopeActive() n'existe plus, il a donc fallu faire sans
  • Dans les fichiers YML, il restait quelques chaines sans quotes, qui contenaient des ":". Depuis Symfony 3, le composant YML lève une exception de parsing dans ce cas-là.
  • Quelques configurations de FormType qui n'existent plus, comme pattern, precision, property, etc. Voir la liste ici.
  • Comme l'option choices_as_values n'existe plus, il a fallu repasser sur tous les CollectionType : pour les valeurs du sous-formulaire, avant on passait en clef la valeur à stocker, et en valeur, le libellé à afficher. Maintenant, c'est l'inverse.
  • {% render() %} n'aurait pas du être appelé comme ça, mais plutôt {{ render() }}. C'est obligatoire maintenant.
  • La configuration twig.form.resources devient twig.form_themes
  • La configuration security.firewalls.foo.form_login.csrf_provider: form.csrf_provider devient security.firewalls.foo.form_login.csrf_token_generator: security.csrf.token_manager

Benchmarks entre Symfony 2.8.4 et Symfony 3.1.0


Il faut bien prendre en compte que ces benchmarks sont à tire informatif. Ils ont été fait sur mon PC, donc avec une interface graphique très gourmande, avec Apache Bench, PHP 5.6, sur la page de connexion de mon projet.
Pour chacune des concurrences d'accès, 1 000 appels sont effectués. Le temps affiché est le temps moyen d'une requête. L'environnement est spécifié à côté de la version de Symfony.

Concurrence 1 Concurrence 3 Concurrence 5 Concurrence 10
Symfony 2.8.4
(prod)
81.329 ms
(12.30 req/s)
97.185 ms
(30.87 req/s)
114.103 ms
(43.82 req/s)
218.755 ms
(45.71 req/s)
Symfony 3.1.0
(prod)
113.321 ms
(8.82 req/s)
138.314 ms
(21.69 req/s)
152.142 ms
(32.86 req/s)
299.432 ms
(33.40 req/s)
Symfony 2.8.4
(dev)
230.995 ms 287.655 ms 342.507 ms 672.107 ms
Symfony 3.1.0
(dev)
243.499 ms 301.299 ms 358.609 ms 692.711 ms

On constate donc que l'environnement de prod est environ 3x plus rapide que l'environnement de dev.
Symfony 3.1 est 28% plus lent que Symfony 2.8.4 !