如果类映射实际上更快,为什么要在作曲家中使用PSR-0或PSR-4自动加载?

2022-08-30 14:42:35

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

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

./composer.phar dump-autoload -o

答案 1

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

类映射的速度来自于在执行加载文件,解析文件(操作码缓存将在此处提供帮助)然后执行文件的始终必要的工作之前,不必检查文件系统是否存在。

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

我发现了两个讨论这个主题的资源:首先,github问题#1529建议使用一堆符号链接对作曲家自动加载器进行进一步改进,以避免必须扫描多个目录。

那里的讨论还表明,您实际上应该尝试在PSR-0自动加载声明中使用最佳的命名空间或类名前缀,即尽可能长的前缀。还可以在声明中使用多个前缀。

然后,该期杂志中链接了一篇博客文章,其中记录了一些使用股票EZPublish 5的xhprof基准测试,并摆弄了这些设置,包括APC缓存和classmap转储。

货币报价:

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

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

请注意,您只能获得每个请求的低个位数毫秒。如果这个数字在5%到10%的范围内显着提高性能,那么您的应用程序肯定会很棒。但是,如果您真的处于该性能范围内,盲目地认为类映射始终更快可能会浪费大量不必要的CPU周期。

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


答案 2

如果类映射实际上更快,为什么要在作曲家中使用PSR-0或PSR-4自动加载?

因为它更实用。

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

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


推荐