提供一些背景信息:
我最近与一位同事讨论了在PHP中使用Autoloader的问题。我赞成他们,反对他。
我的观点是Autoloaders可以帮助您最小化手动源依赖性,这反过来可以帮助您减少包含许多您可能不需要的大型文件所消耗的内存量。
他的回答是,包含你不需要的文件并不是一个大问题,因为一旦文件被包含在内,一旦它由Apache子进程保存在内存中,这部分内存将可用于后续请求。他认为你不应该关心所包含文件的数量,因为很快就会将它们全部加载到内存中并从内存中按需使用。因此,内存不是问题,尝试在文件系统上找到所需文件的开销更令人担忧。
他是一个聪明人,往往会知道他在说什么。但是,我一直认为Apache和PHP使用的内存特定于正在处理的特定请求。 每个请求都分配了一个等于memory_limit PHP选项的内存量,任何源编译和处理仅在请求的生命周期内有效。
即使使用像APC这样的操作码缓存,我还是认为单个请求仍然需要在其自身的内存部分中加载每个文件,并且APC只是将其预编译为回应过程。
我一直在搜索关于此的一些文档,但到目前为止还没有设法找到任何东西。如果有人能指出我关于这个主题的任何有用的文档,我将非常感激。
更新:
为了澄清,自动加载器讨论部分更多的是上下文:)。
可能还不是很清楚,但我的主要问题是Apache是否会将其资源集中在一起以响应多个请求(尤其是包含文件使用的内存),或者每个请求是否需要检索满足与同一进程处理的其他请求隔离的执行路径。
例如为: 文件1,2,3和4的大小相等,每个大小为100KB。 请求A包括文件1,2和3。 请求B包括文件1,2,3和4。
在他看来,他认为请求A将为其全部执行消耗300KB而请求B将仅消耗100KB,因为文件1,2和3已经在内存中。 / p>
在我看来,它是300KB和400KB,因为它们都是独立处理的(如果是同一个过程)。
这让他回到了他的论点,即#34;只是包括这个地段'因为你无论如何都要使用它"而不是我的#34;只包括你需要保持请求大小的东西"。
这对于我如何建立一个PHP网站非常重要,所以我很想知道我是不是在这里。
我一直认为大型网站内存是最宝贵的资源,而不是文件系统检查自动加载器的问题,而内核可能是由内核缓存的。
你是对的,是时候进行基准测试了!
答案 0 :(得分:4)
以下是你如何赢得争论:运行现实的基准,并在数字的右侧。
我有同样的讨论,所以我尝试了一个实验。使用APC,我尝试了一个Kohana应用程序,其中包含单个整体包含(包含所有Kohana)以及标准自动加载器。最终结果是单个包含在统计上不相关的速率(小于1%)更快但使用了更多的内存(根据PHP的内存函数)。没有APC(或XCache等)运行测试是没有意义的,所以我没有打扰。
所以我的结论是继续使用自动加载,因为它使用起来要简单得多。尝试使用您的应用程序,向朋友展示结果。
现在你不需要猜测。
免责声明:我没有使用Apache。我无法强调在您自己的应用上在自己的硬件上运行自己的基准测试。不要相信我的经验会属于你。
答案 1 :(得分:2)
你是狡猾的忍者,蚱蜢。
在请求类之前,自动加载器不会加载类文件。这意味着它们将使用与手动包含相同数量的内存,但通常要少得多。
即使apache线程可以处理多个请求,每个请求都会从文件中读取新类,因此您的朋友的所有内容都会被读取'不能保留水。
你可以通过回音'foo'证明这一点;在类文件中的类定义之上。无论您是在开始时自动加载还是手动包含整个类文件,您都会在每个新请求中看到该行将被执行。
我找不到任何关于此的简明文档 - 我可能会用一些内存使用示例写一些 - 因为我还必须向其他人解释这一点并显示证据让它陷入其中。我认为在zend的人们并不认为任何人都不会看到自动加载的好处。
是的,apc等(像所有缓存解决方案一样)可以克服资源负面因素,甚至可以获得性能上的小幅提升,但是如果你在非常重要的数量的库和服务上执行此操作会占用大量不必要的内存大量的客户。尝试一些事情就像在一个庞大的包含文件中加载一个健康的梨库一样,同时处理500个连接同时击中你的页面。
即使使用像Apc这样的东西,你也可以使用自动加载器和任何非命名空间类(目前大多数现有的PHP代码),因为它可以帮助避免在处理大型类库时对全局命名空间的污染。
答案 2 :(得分:0)
这是我的意见。
我认为自动加载器是一个非常糟糕的主意,原因如下
对于内存/性能问题,如果计算机遇到困难,为计算机购买更多内存也同样便宜。