it-roy-ru.com

Зачем использовать автозагрузку PSR-0 или PSR-4 в composer, если карта классов на самом деле быстрее?

Я понимаю, что вы можете использовать либо стандарт PSR для поиска файлов, либо указать composer каталог для поиска классов. Стандарт документация рекомендует использовать PSR-4 . Для composer также существует опция для создания оптимизированный автозагрузчик, который в основном генерирует полную карту классов . Так зачем вообще использовать PSR-4, если лучший способ загрузки - это карта классов?

Для меня имеет смысл сохранить структуру каталогов, поскольку в любом случае это хороший способ организации. Однако кажется, что логичным вариантом было бы использовать загрузку PSR-4 на машинах разработки, а затем карту классов для производственной среды. Таким образом, вам не нужно перестраивать свою таблицу классов каждый раз, когда вы создаете новый класс, но производственная среда создает полную как часть процесса развертывания без дополнительного вызова

./composer.phar dump-autoload -o
29
Bryan Agee

Зачем использовать автозагрузку PSR-0 или PSR-4 в composer, если classmap на самом деле быстрее?

Потому что это более практично.

В производстве вы можете использовать карту классов (с composer dumpautoload -o), потому что вы не добавите новый класс, но в среде разработчиков интересно иметь гибкость, обеспечиваемую PSR-0 или PSR-4 (то есть ничего не делать при добавлении новых классов) ).

Обновление: Вы также можете использовать composer install -o, это проще.

32
Matthieu Napoli

Проблема в том, что карта классов на самом деле не быстрее в каждом случае!

Скорость карты классов заключается в том, что нет необходимости проверять файловую систему, если файл существует, прежде чем выполнять всю необходимую работу по его загрузке, синтаксическому анализу (здесь помогут кэши opcode) и затем его выполнению.

Но недостатком карты классов является то, что вы, возможно, генерируете огромное количество данных для каждого отдельного класса, интерфейса и свойства, включенного в библиотеки, которые вы используете, без фактического использования их в вашем рабочем коде. Загрузка огромных массивов не происходит бесплатно - хотя код не нужно анализировать снова и снова (кэш кода операции), он все равно должен выполняться, структура данных массива должна быть помещена в память, заполнена множеством строк, а затем пожирает некоторое количество памяти, которое могло бы быть использовано для чего-то другого.

Я нашел два ресурса, обсуждающих эту тему: во-первых, есть проблема github # 1529 предлагающая дальнейшие улучшения для автозагрузчика композитора, использующие кучу символических ссылок, чтобы избежать необходимости сканировать несколько каталогов.

Обсуждение там также показывает, что на самом деле вы должны попытаться использовать наилучший из возможных префикс пространства имен или имени класса в объявлении автозагрузки PSR-0, то есть самый длинный из возможных. Вы также можете использовать более одного префикса в объявлении.

Затем есть сообщение в блоге, связанное с этой проблемой которое документирует некоторые тесты xhprof, используя стандартную версию EZPublish 5 и изменяя настройки, включая APC Caching и дамп карты классов.

Цитата денег:

Эта команда создала файл 662KiB vendor/composer/autoload_classmap.php, содержащий массив, представляющий собой хэш, состоящий из имени класса в качестве индекса и пути к файлу, содержащему определение класса в качестве значения. На момент написания этого поста этот массив состоит из 4168 записей . [...] Хотя он должен дать нам наиболее эффективный механизм автозагрузки, он на самом деле замедляет работу (с 254,53 запросов в секунду до 197,95). Причина в том, что даже если файл кэшируется APC, массив PHP, содержащий карту с более чем 4100 записями, необходимо пересоздавать при каждом отдельном запросе. 

Будет ли карта классов быстрой? Конечно. Самый быстрый в каждом случае? Конечно, нет - это зависит от соотношения используемых и неиспользуемых классов на запрос. Таким образом, даже если в среднем ваше приложение фактически использует ВСЕ классы на карте, карта классов может все еще работать медленнее, если вы используете только около 10% классов на запрос, и вам лучше оптимизировать объявления автозагрузки используемых вами библиотек. , Фактически, каждый префикс имени класса должен указывать только на один каталог.

Обратите внимание, что выигрыш в производительности, который вы могли бы получить, составляет лишь около одной миллисекунды с одной цифрой на запрос. Ваша заявка, безусловно, великолепна, если эта цифра значительно увеличивает производительность в диапазоне от 5 до 10%. Но если вы действительно находитесь в этом диапазоне производительности, слепо полагая, что карта классов ВСЕГДА быстрее, вероятно, тратит много ненужных циклов ЦП.

Если вы оптимизируете что-то: измерьте это! Как бы вы узнали, станет ли на самом деле лучше, если вы не можете измерить это?

45
Sven

вот что вам нужно сделать, если вы добавили/изменили классы:

  • classmap: dumpautoload composer (возможно, также обновите composer.json новой записью classmap)
  • PSR-0: ничего
  • PSR-4: ничего

так что в основном вы можете сойти с ума с psr-4 и psr-0, не беспокоясь о том, правильно ли ваш вновь созданный класс находится в автозагрузчике. Кроме того, вы получаете правильную структуру каталогов free вашей библиотеки, которая представляет ваше пространство имен.

файлы автозагрузчика:

  • карта классов: vendor/composer/autoload_classmap.php
  • psr-0: vendor/composer/autoload_namespaces.php
  • psr-4: vendor/composer/autoload_psr4.php
9
zwacky

Важным аргументом здесь является то, что использование psr-4 или psr-0 в composer.json заставляет организовать ваши файлы классов в соответствии со строгим стандартом. Это позволяет другим (или вам самим через 2 года), которые смотрят на composer.json, сразу узнать, где находятся ваши классы.

Если вы делаете это неправильно, например, если вы ошиблись в написании пространства имен, вы, скорее всего, узнаете об этом во время разработки или в своих модульных тестах из-за «класса не найден». Это хорошо, потому что это заставляет вас это исправить.

Карта классов намного более простительна и позволит любую произвольную организацию файлов классов, оставляя читателя в неведении.

Итак, как уже говорили другие: используйте psr-4 или psr-0 в composer.json, работайте с этим во время разработки, а затем рассмотрите опцию -o для производства. Но оцените, действительно ли это приносит выигрыш в производительности!

2
donquixote

Проблема с PSR-0 и PSR-4 (и картой классов) при ее реализации не учитывает оптимизацию. Реализация отсутствует в лучшем случае.

Однако идея, лежащая в основе карты классов, работает.

Я создал библиотеку, которая работает, генерируя карту классов. Тем не менее, эта карта классов намного проще, но оптимизирована.

https://github.com/eftec/autoloadone

Карта уменьшается даже для большого проекта, она группирует одни и те же классы одного и того же пространства имен, если они содержатся в одной папке. Если нет, то это не проблема, они также включены. Также, если у класса отсутствует пространство имен, два класса в файле, файл находится вне области видимости, это не проблема, он отслеживает их все. Вы можете даже исключить некоторые папки или пространство имен. 

Например, в большом проекте

Number of Classes: 898
Number of Namespaces: 62
Number of Maps: 117
Number of PHP Files: 1693
Number of PHP Autorun: 0
Number of conflict: 1
Ratio map: 6.91% (less is better. 100% means one map/one file)
Map size: 12.9 kbytes (less is better, it's an estimate of the memory used by the map)

Так, для проекта с 898 классами карта использует только 12,9 КБ. 

А какая разница в производительности:

  • ему не нужно сканировать папку (например, если файл не существует).
  • он не проверяет, не существует ли файл. 
  • это всего лишь один файл. Таким образом, накладные расходы являются одним включением, а не 3 для 

Автозагрузка Composer включает (для каждого вызова) следующие файлы: 

  • autoload.php
  • composer/ClassLoader.php (зависит от конфигурации)
  • композитор/autoload_real.php
  • композитор/autoload_namespaces.php
  • композитор/autoload_psr4.php
  • composer/autoload_classmap.php (89 КБ)

или он запускает файлы:

  • autoload.php
  • composer/ClassLoader.php (зависит от конфигурации)
  • composer/autoload_static.php (107 КБ)

В то время как Opcache удивляет, но мы все еще включаем, по крайней мере, два включения (вместо одного), плюс одно из них огромно, и это все еще накладные расходы, и это все еще за вызов.

Итак, что быстрее. Это зависит от проекта, но я проверил, что обычно PSR-0 быстрее. Однако разница невелика, оба медленные. :-П

0
magallanes