Pourquoi utiliser un autoload PSR-0 ou PSR-4 dans composer si classmap est en fait plus rapide?

je comprends que vous pouvez utiliser soit un standard PSR pour localiser des fichiers, ou dire à composer un répertoire pour rechercher des classes. la documentation recommande l'utilisation de la norme PSR-4 . il y a aussi une option pour composer pour créer un Autoloader optimisé, qui génère essentiellement une classmap complète . Alors pourquoi utiliser PSR-4 si la meilleure façon de charger est avec classmap?

il fait sens à moi de garder la structure de répertoire, puisque c'est une bonne façon d'organiser de toute façon. Cependant, il semble que l'option logique serait D'utiliser le PSR-4 sur les machines de développement, puis classmap pour l'environnement de production. De cette façon, vous n'avez pas à reconstruire votre classmap à chaque fois que vous créez une nouvelle classe, mais l'environnement de production en crée une complète dans le cadre du processus de déploiement sans appel supplémentaire à

./composer.phar dump-autoload -o
28
demandé sur Mark Fox 2014-04-02 10:42:57

5 réponses

Pourquoi utiliser un autoload PSR-0 ou PSR-4 dans composer si classmap est en fait plus rapide?

parce que c'est plus pratique.

dans la production, vous pouvez utiliser une classmap (avec composer dumpautoload -o ) parce que vous n'ajoutez aucune nouvelle classe, mais dans l'environnement dev il est intéressant d'avoir la flexibilité fournie par PSR-0 ou PSR-4 (c.-à-d. rien à faire lors de l'ajout de nouvelles classes).

mise à Jour: vous pouvez aussi utiliser composer install -o , c'est plus simple.

32
répondu Matthieu Napoli 2015-05-26 18:15:44

le problème est que classmap n'est pas vraiment plus rapide dans tous les cas!

la vitesse de classmap vient de ne pas avoir à vérifier le système de fichiers si un fichier existe avant de faire le travail toujours nécessaire de le charger, de le parser (les caches opcode vous aideront ici) et de l'exécuter.

mais l'inconvénient de classmap est que vous générez éventuellement une énorme quantité de données pour chaque classe, interface et trait inclus dans le bibliothèques que vous utilisez, sans que vous l'utilisiez réellement dans votre code de production. Le chargement de tableaux énormes ne vient pas gratuitement - alors que le code n'a pas besoin d'être analysé encore et encore (opcode cache), il doit encore être exécuté, la structure de données de tableau doit être mis en mémoire, rempli de beaucoup de chaînes, et mange ensuite une certaine quantité de mémoire qui pourrait avoir été utilisable pour quelque chose d'autre.

j'ai trouvé deux ressources discutant de ce sujet: tout d'abord il ya github numéro 1529 suggérant d'autres améliorations pour le compositeur autoloader en utilisant un tas de liens symboliques pour éviter d'avoir à scanner plusieurs répertoires.

la discussion là - bas révèle aussi que vous devriez en fait essayer d'utiliser le meilleur préfixe namespace-ou classname-possible dans la déclaration PSR-0 autoload, c'est-à-dire le plus long possible. Vous pouvez également utiliser plus d'un préfixe dans la déclaration.

puis il y a un billet de blog lié dans ce numéro qui documente certains benchmarks xhprof en utilisant un EZPublish 5 stock et en jouant avec les paramètres, y compris la mise en cache APC et le dumping classmap.

de l'Argent citation:

cette commande crée un vendeur/compositeur/autoload_classmap de 662KiB.fichier php contenant un tableau qui est un hachage composé du nom de classe comme index et du chemin vers le fichier contenant la définition de classe comme valeur. Au moment où j'écris ce la poste, ce tableau est composé de 4168 entrées. [...] Bien qu'il devrait nous donner le mécanisme d'autoloading le plus efficace, il ralentit effectivement les choses (de 254,53 reqs/seconde à 197,95). La raison étant que même si le fichier est mis en cache par APC, le tableau PHP contenant la carte avec plus de 4100 entrées doit être recréé à chaque requête.

est-ce qu'une classmap sera rapide? Certainement. Plus rapide dans tous les cas? Bien sûr que non, ça dépend de l' le rapport vs classes non utilisées par demande. Ainsi, même si votre application utilise en moyenne toutes les classes de la carte, une classmap pourrait être plus lente si vous n'utilisez qu'environ 10% des classes par requête, et vous feriez mieux d'optimiser les déclarations autoload des bibliothèques que vous utilisez. En fait, chaque préfixe de classname ne devrait jamais pointer que vers un seul répertoire.

notez que le gain de performance que vous obtiendriez seulement est dans la zone d'environ bas à un chiffre millisecondes par demande. Votre application est sûrement génial si ce chiffre est une augmentation de performance significative dans la gamme de 5 à 10%. Mais si vous êtes vraiment dans cette plage de performances, croire aveuglément qu'une classmap est toujours plus rapide gaspille probablement beaucoup de cycles CPU inutiles.

si vous optimisez quelque chose: mesurez-le! Comment le sauriez-vous si cela devient réellement meilleur si vous ne pouvez pas le mesurer?

44
répondu Sven 2014-04-02 22:03:27

voici ce que vous devez faire, si vous avez ajouté/ changé de classe:

  • classmap: composer dumpautoload (peut-être aussi mettre à jour composer.JSON avec une nouvelle entrée classmap)
  • psr-0: rien
  • psr-4: nothing

donc fondamentalement, vous pouvez aller sauvage avec psr-4 et psr-0 sans avoir à s'inquiéter, si votre classe nouvellement créée est correctement dans le chargeur automatique. plus avec elle vous obtenez un libre structure de répertoire propre de votre bibliothèque, qui représente votre espace de nom.

fichiers autoloader:

  • classmap: vendeur/compositeur/autoload_classmap.php
  • psr-0: vendeur/composer/autoload_namespaces.php
  • psr-4: vendeur/compositeur/autoload_psr4.php
9
répondu zwacky 2016-03-20 22:31:52

un argument important ici est que l'utilisation de psr-4 ou psr-0 dans le compositeur.json forces vous d'organiser vos dossiers de classe en suivant une norme stricte. Cela permet aux autres (ou à vous-même dans 2 ans) qui regardent le compositeur.json immédiatement savoir où votre classe.

si vous faites cela mal, par exemple si vous avez mal orthographié un espace de noms, alors vous le découvrirez probablement pendant le développement ou dans vos tests unitaires à cause d'une"classe non trouvée". Ce c'est bien, parce que ça te force à arranger ça.

la classmap est beaucoup plus indulgente, et permettra toute organisation arbitraire des fichiers de classe, laissant le lecteur dans l'obscurité.

donc, comme d'autres l'ont déjà dit: Utilisez psr-4 ou psr-0 dans le compositeur.json, travailler avec cela pendant le développement, puis envisager l'option-o pour la production. Mais mesurez si cela apporte vraiment un avantage de performance!

2
répondu donquixote 2014-09-20 14:04:17

la question Est trompeuse.

"classmap" comme l'option de chargement automatique est plus précisément juste un annuaire glob muet avec une référence à chaque fichier qu'il rencontre qui a une classe avec un nom correspondant. Il compile ensuite tout cela dans le "tableau classmap", qui contient également des règles PSR-0.

donc, PSR-0 et classmap utilisent le même classmap, ce qui signifie qu'il n'y a littéralement aucune différence.

vous utilisez PSR-0 parce que vous voulez un code PSR-0 autoload.

-1
répondu Phil Sturgeon 2014-04-03 08:12:14