只是想知道是否有人有关于“成本”与包含一个包含100个类文件的大型(600K或更多)php文件相关联的信息。与自动加载单个文件(例如在找到匹配项之前搜索多个目录)相比,它真的有很大的不同吗?
APC缓存会使这个成本微不足道吗?
答案 0 :(得分:21)
基本上,包含一个大文件的成本取决于您的用例。假设您有一个包含200个类的大文件。
如果您只使用1个类,那么包含大文件将比为该个别类包含一个小类文件更昂贵。
如果你使用所有200个类,包括大文件将比包含200个小文件便宜得多。
截止位置实际上取决于系统。我会想象它会在大约50%的标记处(如果你在任何一个请求中使用少于100个类,那么自动加载)。
使用APC可能会使盈亏平衡点更接近较少的类别(因此没有,使用的100个类可能是盈亏平衡点,但可能会使用50个类),因为它使得大单个包含更便宜,但是只会略微降低每个人的开销。
确切的盈亏平衡点将取决于系统100%(磁盘I / O的速度,处理器的速度,内存量等)。因此,在您的平台上确定的唯一方法是测试。
然而,与原始表现相比,更多的是利害关系。可维护性将受到一个大文件的影响,因为同时处理多个类更难(IDE中的选项卡变得无用)。我个人会将所有课程保存在单独的文件中,让我的开发人员更轻松,而不是制作文件的巨大怪物。
现在,如果你有facebook流量水平,可能值得进一步调查。但如果你不是,我个人不会担心......
答案 1 :(得分:13)
我已经对我要分享的php include()
的各种成本进行了一些测试,因为我看到许多程序员或CMS平台忽略了这些运行前的php成本。
功能本身的成本可以忽略不计。 100个文件包含(空文件)成本约5ms;使用opcache时不超过1微秒。
因此,包含一个包含100个类的较大php文件而不是100个单独文件包含的成本节省仅约5ms。使用OpCode缓存会降低成本。
实际成本来自于文件的大小,以及PHP必须解析和/或编译的内容。为了更好地了解这些成本是什么,这里是我在2010 Mac Mini Server上进行的测试结果,带有10,000 RPM驱动器,运行PHP 5.3并启用了优化器eAccelerator opcache。
1µs for 100 EMPTY File includes, w/opcache
5ms for 100 EMPTY File includes, no opcache
7ms for 100 32KB File includes, w/opcache
30ms for 100 32KB File includes, no opcache
14ms for 100 64KB File includes, w/opcache
60ms for 100 64KB File includes, no opcache
22ms for 100 128KB File includes, w/opcache
100ms for 100 128KB File includes, no opcache
38ms for 100 200KB File includes, w/opcache
170ms for 100 200KB File includes, no opcache
因此,600KB的php文件大约花费6ms,或者使用操作码缓存大约需要1ms。你真正想要看的是每个请求包含的所有代码的大小。
在组合中合并文件以尝试保存资源绝对不是一个好主意,并且在使用op-cache时会出错。如果有的话,我的测试不会非常考虑磁盘速度,因为我将相同的文件包含了100次。这就是说我觉得根本不需要覆盖磁盘I / O,因为安装op-cache实际上是基本性能方面的先决条件。
为了尽可能地提高性能并节省RAM使用率,必须采取相反的措施。通过使用自动加载器或类工厂模式,尽可能多地在上下文中拆分文件,以便为每个请求包含尽可能少的未使用代码。
为此,misusing include_once()
也会产生负面的绩效后果......
关于你的基类。我有类似的情况,但我只包括表模式的一小部分。主要是字段类型和主键详细信息。出于性能原因,我故意不会一直包含表格中相当繁重的模式,因为它们很少使用,当它们存在时,我每次请求只使用其中的几个。
每个架构阵列的表的平均完整列详细信息大约为20-50k。在任何给定的请求中包括10-15个它们的成本仅为1-3毫秒。这本身并不多。但是,当每个请求节省500k RAM时,它变得值得。
答案 2 :(得分:1)
您更愿意在特定类中使用更动态的方法和隔离特定功能。然后,对于每个页面,您可以选择所需的代码。
特别是当您使用APC时,这种方法会更好,因为您没有从磁盘加载许多小文件时将拥有的文件I / O开销。我会选择实现小的指定类,并将每个类放在一个单独的文件中。您可以使用PHP类加载机制(__autoload)自动加载正确的单元。
当您为类和单元找出一个好的命名约定时,这将使您的开发更容易。