如果classmap实际上更快,为什么在composer中使用PSR-0或PSR-4自动加载?

Bry*_*gee 30 php autoload psr-0 composer-php psr-4

我知道你可以使用PSR标准来定位文件,或者告诉作曲家一个目录来扫描类.文档建议使用PSR-4标准.作曲家还可以选择创建优化的自动加载器,它基本上可以生成完整的类图.那么,如果加载的最佳方式是使用类图,为什么要使用PSR-4呢?

保持目录结构对我来说是有意义的,因为这是一种很好的组织方式.但是,似乎逻辑选项是在开发机器上使用PSR-4加载,然后在生产环境中使用类映射.这样,您不必在每次创建新类时都重建类图,但生产环境会在部署过程中创建一个完整的类,而无需额外调用

./composer.phar dump-autoload -o
Run Code Online (Sandbox Code Playgroud)

Sve*_*ven 46

问题是,在每种情况下,类图实际上都不是更快!

类图的速度来自于在执行始终必要的加载工作之前不必检查文件系统(如果文件存在),解析它(操作码缓存将在这里帮助)然后执行它.

但是类图的缺点是,您可能会为您使用的库中包含的每个类,接口和特征生成大量数据,而无需在生产代码中实际使用它.加载庞大的数组并不是免费的 - 虽然代码不需要一次又一次地解析(操作码缓存),但仍然必须执行,数组数据结构必须放入内存,填充大量字符串,然后吃掉可能用于其他东西的一些内存.

我找到了两个讨论这个主题的资源:首先是github问题#1529,它建议使用一堆符号链接来改进作曲家自动加载器,以避免扫描多个目录.

那里的讨论还揭示了你应该尝试在PSR-0自动加载声明中使用尽可能最好的namespace-或classname-prefix,即最长的可能.您还可以在声明中使用多个前缀.

然后在该问题链接了一篇博客文章,该文章使用股票EZPublish 5记录了一些xhprof基准测试,并摆弄了设置,包括APC缓存和类图转储.

钱报价:

此命令创建了一个662KiB vendor/composer/autoload_classmap.php文件,其中包含一个数组,该数组是由类名作为索引组成的散列,以及包含类定义作为值的文件的路径.在我撰写这篇文章时,这个数组由4168个条目组成.[...]虽然它应该给我们提供最有效的自动加载机制,但它实际上减慢了速度(从254.53 reqs /秒到197.95).原因是即使文件被APC缓存,也需要在每个请求中重新创建包含超过4100个条目的映射的PHP数组.

类图会快吗?当然.每种情况下最快?当然不是 - 它取决于每个请求使用的比率与未使用的类别.因此,即使您的应用程序实际上在地图中实际使用了所有类,如果每个请求只使用大约10%的类,则类图可能仍然会更慢,并且您最好优化使用的库的自动加载声明.实际上,每个classname前缀应该只指向一个目录.

请注意,您实现的性能增益仅在每个请求的低单位数毫秒范围内.如果这个数字在5到10%的范围内显着提升,那么你的应用肯定是非常棒的.但如果你真的处于这个性能范围内,盲目地认为类图总是更快可能会浪费很多不必要的CPU周期.

如果你优化了一些东西:测量它!如果不能测量它,你怎么知道它是否真的变得更好?

  • 如果您要将生产部署配置为转储类映射,请预先+1,预先对实际性能进行基准测试.在我的情况下,性能较差. (3认同)

Mat*_*oli 34

如果classmap实际上更快,为什么在composer中使用PSR-0或PSR-4自动加载?

因为它更实用.

在生产中,您可以使用类映射(with composer dumpautoload -o),因为您不会添加任何新类,但在开发环境中,有趣的是具有PSR-0或PSR-4提供的灵活性(即添加新类时无关) .

更新:你也可以使用composer install -o,它更简单.

  • 什么?额外的工作?哪里?在本地,您运行`composer install`,在生产中运行`composer install -o`.还要输入2个字符... (10认同)
  • 不要忘记`--no-dev:为生产版本禁用autoload-dev规则. (3认同)
  • 这似乎是很多额外的工作; 他们为什么不建议在"autoload"部分使用classmap,在"dev-autoload"部分使用psr-4?这样可以节省额外的命令/部署错误,而无需提供任何帮助. (2认同)
  • 根据文档:`这特别适用于生产,但可能需要一些时间来运行,因此目前默认情况下不会这样做. (2认同)

zwa*_*cky 10

如果您添加/更改了类,那么这就是您需要做的事情:

  • classmap: composer dumpautoload(也许还用一个新的classmap条目更新composer.json)
  • psr-0:什么都没有
  • psr-4:什么都没有

所以基本上你可以疯狂地使用psr-4和psr-0,而不必担心你的新创建的类是否在自动加载器中正确.再加上它,您将获得一个免费的库的目录结构,它代表您的命名空间.

自动加载器文件:

  • classmap: vendor/composer/autoload_classmap.php
  • psr-0: vendor/composer/autoload_namespaces.php
  • psr-4: vendor/composer/autoload_psr4.php