【问题标题】:Is object-oriented PHP slow?面向对象的 PHP 慢吗?
【发布时间】:2010-12-11 17:26:19
【问题描述】:

我以前使用过程式 PHP。后来,我曾经创建了一些类。后来,我学习了 Zend Framework 并开始使用 OOP 风格进行编程。现在我的程序都是基于我自己的框架(有cms的元素,但是没有任何设计in框架),是建立在Zend Framework之上的。

现在它由很多类组成。但是我编程的越多,我就越害怕。我担心我的程序会因为它们而变慢。我害怕添加一个可以帮助我开发但会减慢应用程序的类。

我所知道的是,包含大量文件会降低应用程序的速度(使用 eAccelerator + 将所有代码收集到一个文件中可以将应用程序加速 20 倍!),但我不知道创建新的类和对象是否会降低 PHP 本身的速度。

有人知道吗?

【问题讨论】:

  • 如果你的程序越来越慢,你可以重新考虑你的类结构以及你如何实现你的对象。我从来没有听说过 OOP 比过程式的要慢。
  • 感谢您的编辑,托马斯!一件事:我认为,新标题有点不同的意义。不过,我的英语不好,我不会回滚,只是评论:)
  • @backslash17 我不认为我的程序很慢。但我担心如果再上 10 节课就会变慢。还有50个?还有100个?
  • @backslash:你真的没听说过 OOP 比程序风格慢吗? tinyurl.com/ygyclo9 ;) 这取决于人类何时可以忽略不计 ;)
  • OOP 更难维护,开发更慢。它还为同一任务使用了许多倍的内存,并且还使一切变慢。我仍然想知道 OOP 能提供什么。

标签: php oop performance


【解决方案1】:

这让我很烦。看……程序代码并不总是意大利面条代码,但 OOP 粉丝总是认为它是。我已经用 PHP 编写了几个基于过程的 Web 应用程序以及一个 IRC 服务守护程序。令人惊讶的是,它似乎胜过大多数其他的,并且编辑它非常容易。我的一个一般做OOP的朋友看了看说“没有代码有权这么干净”

相反,我编写了自己的 PHP 框架(出于无聊),它是以纯粹的 OOP 方式完成的。

一个优秀的程序员可以编写出色的过程代码,而无需类带来的开销。使用 OOP 的糟糕程序员总是会编写糟糕的 OOP 代码,从而减慢速度。

对于哪个更适合 PHP,没有一个正确答案,而是哪个更适合具体场景。

【讨论】:

  • 确实如此。代码的好坏完全取决于编写它的人,而不是它是面向对象或函数式的。
  • @Jeremy 我想看到你提到的这个非常干净的程序代码的链接。即,“图片或它没有发生。” :)
  • 这里有一个有趣的概念。您能否确认您正在编写哪种类型的 size 应用程序?一个 5 甚至 20 个文件的应用程序,即使有一些数据库访问(等)也可以很容易地在程序中干净编写。但是,当您拥有包含各种组件的较大规模时,我不相信它会粘合在一起以及它会使用大部分(至少是一些)对象路过。
  • PHP 的设计不像 Java 那样面向 OOP 的语言。因此,OOP 设计需要以完全依赖于单个项目的比例与程序化混合,从而在不影响性能的情况下从最佳可维护性中受益。将所有的 OOP 都疯狂地使用它会产生性能问题,这些问题会使 OOP 粉丝远离并激发对语言的仇恨,而程序化的事情可能会产生高性能的代码,它还会在维护和扩展功能方面造成严重的问题。自己想一想,这本书只是一个指南。
  • “一个糟糕的程序员总是会编写糟糕的 OOP 代码,这会减慢速度”BS。一个糟糕的程序员我不太可能写 OOP...
【解决方案2】:

有一些方法可以限制 include_once 条目的惩罚,这是通过在“include_once”文件中声明的函数,这些函数本身的代码内容在“include”语句中。这将加载您的代码库,但只有实际使用的那些函数才会根据需要加载代码。您对包含的代码进行了第二次文件系统访问,但是库本身的内存使用量几乎没有下降,并且只有您的程序使用的代码被加载。可以通过缓存来减轻来自第二个文件系统访问的影响。在处理基于过程的大型 PHP 项目时,这提供了低内存使用和快速处理。不要在课堂上这样做。这适用于生产实例,开发服务器将显示所有命中损失,因为您不想打开缓存。

【讨论】:

    【解决方案3】:

    如果你设计一个巨大的 OOP 对象,它会做所有事情而不是对各种类进行功能分解,你显然会用无用的镇流器代码填满内存。此外,使用缓慢的框架,您将无法快速创建一个简单的 hello World。我注意到这是一种趋势(坏习惯),对于一个单独的 facebook 图标,人们包含一个很棒的字体库,然后是一个包含 fontello 的搜索图标。每次他们完成一些不寻常的事情时,他们都会连接整个框架。如果您想创建一个快速加载的 oop 应用程序,请仅使用一个框架,例如 zephir-phalcon 或任何您喜欢的框架并坚持下去。

    【讨论】:

      【解决方案4】:

      如果您的项目包含许多文件,并且由于 PHP 的文件访问检查和限制的性质,我建议打开 realpath_cache,将配置设置提高到合理的数字,然后关闭 open_basedir 和 @ 987654325@。确保使用 PHP-FPM 或 SuExec 在用户 ID 下运行 php 进程,该用户 ID 仅限于文档根目录,以获取通常从 open_basedir 和/或 safe_mode 获得的安全性。

      以下是为什么这是性能提升的几点提示:

      还要考虑我对@Ólafur 回答的评论:

      我发现尤其是自动加载是最大的减速。 PHP 在目录查找和文件打开访问方面非常慢,在自定义自动加载器期间使用的 PHP 函数越多,速度越慢。您可以通过关闭安全模式(无论如何都不推荐)甚至是 open-basedir 来帮助它(但我不会这样做),但最大的改进来自不使用自动加载并简单地使用带有完整 fs 的“require_once”需要您使用的每个 php 文件的所有依赖项的路径。

      【讨论】:

      • +1 获取信息,但不是主要问题的答案;)
      【解决方案5】:

      这里是good article discussing the issue. 我还看到了一些anecdotal bench-marks,这将使 OOP PHP 开销达到 10-15% 就我个人而言,我认为 OOP 是更好的选择,因为最终它可能会表现得更好,因为它可能经过更好的设计和深思熟虑。程序代码往往很混乱且难以维护。所以最后 - 它必须是您的应用程序的性能差异与维护、扩展和简单理解的能力之间的关键程度

      【讨论】:

      • 谢谢! (顺便说一句,轶事基准测试中的脚本 B 是否有效?我认为,$basket 应该通过引用传递。或者我太 C-lish?:)
      • 恕我直言,永远不要盲目地选择一个或另一个。如果脚本很小,并且您需要完整的性能,请使用程序,尝试编写尽可能少的意大利面条。如果脚本(不是项目,我的意思是脚本.. 大项目有很多小脚本,一些在 oop 中,一些在程序中)并且您需要完全可维护性,请使用 oop。
      • 我同意,我(有点)在最后提出同样的观点
      • 当你试图解决一个问题时,OOP 会让你更难以思考,所以用 OOP 制作的程序设计得更糟,性能也很差。 OOP 往往比较混乱且难以维护,但也会大大增加给定程序的代码量。
      • 那么最后,你在回答什么你没有经验的问题?别再对人撒谎了。
      【解决方案6】:

      正如其他几个人所指出的那样,OO PHP 的开销很小,但您可以通过将优化工作集中在其他各种类派生自的核心类上来抵消它。这就是 C++ 在高性能计算领域(传统上是 C 和 Fortran 领域)越来越受欢迎的原因。

      就我个人而言,我从未见过受 CPU 限制的 PHP 服务器。检查您的 RAM 使用情况(您也可以为此优化核心类)并确保您没有进行不必要的数据库调用,这比您正在进行的任何额外 CPU 工作的成本要高出几个数量级。

      【讨论】:

        【解决方案7】:

        是的,每个包含都会使您的程序变慢,但不止于此。

        如果您将程序分解为多个文件,那么在某一点上,您包含/解析/执行的代码量最少,而包含所有这些文件的开销。

        此外,拥有大量文件而代码很少,因为正如您所说,使用 eAccelerator 或 APC 之类的东西是获得大量性能的简单方法。同时,如果您相信它们,您将获得拥有面向对象代码库的所有美妙好处。

        此外,每个请求的速度都很慢!= 不可扩展。

        更新

        根据要求,PHP 在直接数组操作方面仍然比在类方面更快。我依稀记得学说 ORM 项目,有人比较了数组与对象的水合,结果数组出来得更快。这不是一个数量级,但值得注意的是——this is in french, but the code and results are completely understandable.。请注意,该学说使用了很多魔术方法 __get 和 __set,而且这些方法也比显式变量访问慢,学说的对象水合缓慢的部分原因可能是由于这一点,因此我将其视为最坏的情况。最后,即使您使用的是数组,如果您必须在内存中进行大量移动,或者需要大量测试,例如 isset,或者像 'in_array' 之类的函数(它的顺序为 N),您将搞砸性能好处。还要记住,对象只是下面的数组,解释器只是将它们视为特殊对象。就我个人而言,我更喜欢更好的代码而不是性能的小幅提升,你会从拥有更智能的算法中获得更多好处。

        【讨论】:

        • 哦,谢谢最后一行!它消除了我的很多疑虑 :) 其他行呢,正如我所说,我知道包含和询问类本身:)
        【解决方案8】:

        您可以重新考虑重新考虑您的类结构以及如何实现它们。如果您说 OOP 速度较慢,您可能必须重新设计您的类以及如何实现它们。类只是对象的模板,任何设计不当的方法都会影响该类的所有对象。

        尽可能多地使用继承和多态性,这将有效地减少你的类需要的行为和独立方法的数量,但首先你需要创建一个好的继承映射,尽可能多地抽象你的第一个或母类可以。

        你有多少类不是问题,问题是它们有多少方法、属性或字段,以及这些方法的结构如何。继承大大减少了设计方法的数量和要编译的代码量。

        【讨论】:

        • 我没有说过'OOP 更慢'。我问过,是不是。
        【解决方案9】:

        要记住的最重要的事情是,先设计,后优化。更好的设计,更易于维护,比意大利面条式代码更好。否则,您不妨在汇编程序中编写您的 Web 应用程序。完成后,您可以分析(而不是猜测)并优化看起来最慢的部分。

        【讨论】:

        • profiling php 真是令人头疼(为了读取 XDebug 的文件,我必须使用 Linux。或者使用不显示任何信息的奇怪的 Air 应用程序,但只将文件转换为其他奇怪的格式。或者我可以使用 Zend Debugger,但我现在不想购买 Zend Studio)
        • Wincachegrind 可以很好地为我读取 Windows 下的分析器输出。
        • 还有 webcachegrind,它是 xdebug 配置文件日志的漂亮接口。
        • 使用 Xdebug 研磨器确定要优化的内容。还可以使用 Intellij 单步执行代码并查看发生了什么,这非常有帮助。对于那些发现这些工具很复杂的人,只需使用 php 内置的 tick 或使用自动加载器或添加一些标记来计时或全部。有大量的基准测试工具。你没有借口。 php.net/manual/en/…
        【解决方案10】:

        为 Web 应用程序使用大型框架实际上并不需要如此多的类来处理所有事情,这可能是许多人没有意识到的最严重的问题。至少去掉它,不要包含所有代码,只保留你需要的,然后扔掉剩下的。

        【讨论】:

          【解决方案11】:

          如果您使用的是 include_once(),那么无论是否采用 OOP 设计,都会导致不必要的减速。

          OOP 会给您的代码增加开销,但我敢打赌您永远不会注意到它。

          【讨论】:

          • 哦,谢谢,我想我应该记住它。顺便说一句,我不经常使用包含。我更喜欢自动加载文件,然后测试并在一个文件中收集大部分文件,然后上传到生产环境
          • 我发现尤其是自动加载是最大的减速。 PHP 在目录查找和文件打开访问方面非常慢,在自定义自动加载器期间使用的 PHP 函数越多,速度越慢。您可以通过关闭安全模式(无论如何都不推荐)甚至是 open-basedir 来帮助它(但我不会这样做),但最大的改进来自不使用自动加载,而只需使用带有完整 fs 的“require_once”需要您使用的每个 php 文件的所有依赖项的路径。
          猜你喜欢
          • 2014-08-25
          • 2010-11-17
          • 2011-03-26
          • 2010-09-11
          • 1970-01-01
          • 2011-04-28
          • 2011-02-27
          • 1970-01-01
          • 2011-07-25
          相关资源
          最近更新 更多