【问题标题】:What's the performance cost of "include" in PHP?PHP中“包含”的性能成本是多少?
【发布时间】:2011-06-20 22:06:55
【问题描述】:

只是想知道是否有人知道与包含 100 多个类文件的大型(600K 或更多)php 文件相关的“成本”信息。与自动加载单个文件(例如在找到匹配项之前搜索多个目录)相比,它真的有很大不同吗?

启用 APC 缓存是否会使此成本可以忽略不计?

【问题讨论】:

  • 澄清一下,这将是 ORM 的“基类”。没有简单的方法可以通过“功能”来区分它们,它们只是数据库模式的表示。我们在每个“构建”上覆盖它们,目前我们为对象和表级别覆盖扩展了两次。对于任何给定的请求,我们可能会加载其中的 10-15 个。在我最初的测试中,我发现加载完整文件与不加载文件之间没有明显区别。我们确实启用了 APC,所以也许这是其中的一部分?
  • 为什么需要在 PHP 脚本中包含整个数据库模式?给定的脚本只需要知道它将与之交互的模式的少数元素。我能想到的唯一例外是生成整个模式的表示的脚本,但即使在那里,它也可以在不包括 PHP 中的特定数据的情况下实现,只需查询数据库以检索模式。这听起来很臃肿。

标签: php performance php-include


【解决方案1】:

基本上,包含一个大文件的成本取决于您的用例。假设您有一个包含 200 个类的大文件。

如果您只使用 1 个类,包含大文件将比包含单个类的小类文件更昂贵。

如果您使用全部 200 个类,包括大文件将比包括 200 个小文件便宜得多。

截止点实际上取决于系统。我会想象它会在 50% 左右(如果您在任何一个请求中使用的类少于 100 个,则自动加载)。

并且使用 APC 可能会使盈亏平衡点更接近于更少的课程(因此,如果没有,使用 100 个课程可能是盈亏平衡点,但使用 APC 可能是使用 50 个课程),因为它使大型单包含便宜得多,但是只会稍微降低每个较小的包含的开销。

确切的收支平衡点将 100% 取决于系统(您的磁盘 I/O 有多快,您的处理器有多快,有多少内存等)。因此,在您的平台上确定的唯一方法就是测试。

但是,比原始性能更危险。一个大文件会影响可维护性,因为同时处理多个类变得更加困难(IDE 中的选项卡变得无用)。我个人会将所有类保存在单独的文件中,让我作为开发人员的生活更轻松,而不是让文件成为一个巨大的怪物。

现在,如果您的 Facebook 流量水平,可能值得进一步调查。但如果你不是,我个人不会担心......

【讨论】:

  • 此外,如果您发现将所有内容放入一个大文件中获得了足够显着的速度提升,您可以为您的生产环境创建某种“编译”脚本,该脚本将转储所有单独的类到一个文件中。这将使您受益于速度的提高,同时仍然能够在单个文件中维护类。
  • @ircmaxwell: 是的,同意它需要的不仅仅是“foreach($files as $f) cat $f >> onefile.php” 你必须想出一些方案to keep 包括在开发/测试和生产环境之间工作,以及其他一些事情。
  • 我的直觉是阻止 1 个数据库查询比阻止 100 个文件包含更重要,但没有测试它只是猜测。
【解决方案2】:

我已经对 php include() 的各种成本进行了一些测试,我想分享一下,因为我看到许多程序员或 CMS 平台忽略了这些运行前 php 成本。

函数本身的成本可以忽略不计。 100 个文件包含(带有空文件)大约需要 5 毫秒;使用 opcache 时不超过一微秒。

因此,与包含 100 个单独的文件相比,包含 100 个类的较大 php 文件所节省的成本仅为 5 毫秒左右。使用 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 文件大约需要 6 毫秒,使用操作码缓存时大约需要 1 毫秒。相反,您真正想看的是每个请求包含的所有代码的大小。

合并文件以尝试节省资源绝对不是一个好主意,并且在使用操作缓存时会出错。我的测试根本没有考虑磁盘速度,因为我包含了同一个文件 100 次。也就是说,我觉得根本不需要讨论磁盘 I/O,因为安装 op-cache 确实是基本性能的先决条件。

要尽可能提高性能并节省 RAM 使用量,必须采取相反的做法。使用自动加载器或类工厂模式尽可能多地根据上下文拆分文件,以尽可能少地为每个请求包含未使用的代码。

为此,misusing include_once() 也可能对性能产生负面影响...

关于您的基类。我也有类似的情况,但我只包含了表架构的一小部分。主要是字段类型和主键细节。出于性能原因,我故意不一直包含这些表的相当繁重的模式,因为它们很少使用,当它们被使用时,我每个请求最多只使用其中的几个。

表的平均完整列详细信息大约为每个模式数组 20-50k。在任何给定的请求中包括 10-15 个,阵列的成本仅为 1-3 毫秒。这本身并不多。但是,当与每个请求节省 500k RAM 相结合时,它就变得值得了。

【讨论】:

  • 最后,用实数代替理论。
【解决方案3】:

APC 会为您节省很多,但我不知道如果您的来源是 600k,它是否可以忽略不计。那是大约 15000 行代码?对于网站来说不算多,但对于单个文件来说却很大。

您宁愿使用更动态的方法并在特定类中隔离特定功能。然后,对于每个页面,您可以选择需要哪些代码。

特别是当您使用 APC 时,这种方法会更好,因为您没有从磁盘加载许多小文件时的文件 I/O 开销。我会选择实现小的、指定的类,并将它们中的每一个放在一个单独的文件中。您可以使用 PHP 类加载机制 (__autoload) 自动加载正确的单元。

当你为你的类和单元找到一个好的命名约定时,这将使你的开发变得容易很多。

【讨论】:

    猜你喜欢
    • 2016-08-27
    • 2010-09-20
    • 1970-01-01
    • 1970-01-01
    • 2018-02-16
    • 2011-02-12
    • 2017-05-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多