PHP性能
在不将软件安装到服务器上的情况下,如何提高PHP脚本的性能/速度?
解决方案
回答
没有神奇的解决方案,而尝试提供通用解决方案很可能只是浪费时间。
瓶颈在哪里?例如,脚本处理器/数据库/内存是否密集?
我们执行过任何分析吗?
回答
每当我看到性能问题时,我认为最好的方法是花时间运行页面多长时间,然后查看最慢的页面。当获得这些真实指标时,通常可以通过修复慢速的SQL查询或者稍微加紧代码来将最慢的指标提高几个数量级。
当然,这不需要新的硬件或者特殊的软件,只需对现有代码进行严格的检查即可。
就是说,这只会持续很长时间……如果我们确实有足够的流量来达到硬件的极限,并且/或者某些代码本来就很慢并且确实需要,那么我们就必须看看其他可能性。
回答
轮廓。轮廓。轮廓。我不确定是否有PHP可用的东西,但是编写一个小工具在代码中插入概要分析信息应该很简单。我们将要分析功能时间和SQL查询时间。
因此,在我们具有功能的地方:
function foo($stuff) { ... return ...; }
我将其更改为:
function foo($stuff) { trace_push_fn('foo'); ... trace_pop_fn('foo'); return ...; }
(这是在一个函数中多次返回成为障碍的情况之一。)
和SQL:
function bar($stuff) { trace_push_fn('bar'); $query = ...; trace_push_sql($query); mysql_query($query); trace_pop_sql($query); trace_pop_fn('bar'); return ...; }
最后,我们可以生成程序执行的完整跟踪,并使用各种技术来识别瓶颈。
回答
我负责大型报告系统,我们会跟踪最慢的报告。当报表开始时,我向数据库中发射一个唯一键,然后在完成时,我可以确定它花费了多长时间。我正在使用数据库,因为这样可以检测页面超时(发生的次数比我想要的多得多)
回答
可以很容易地从货架上撤下的一种合理技术是缓存。通常会花费大量时间来为客户端生成资源,这些资源在请求之间(甚至在客户端之间)是公用的。消除此运行时工作可能会导致速度显着提高。我们可以将生成的资源(或者资源片段)转储到Web树之外的文件中,然后在需要时将其读回。显然,将需要进行一些性能分析以确保它实际上比重新生成要快,否则强制Web服务器定期回到磁盘可能会有害,因此资源确实确实需要大量重用。
我们可能还会感到惊讶,在写得不好的数据库查询中花了多少时间。时间生成的常见查询,看看它们是否可以重写。通常,执行实际的PHP代码所花费的时间是非常有限的,除非我们使用一些次优的算法。
尽管PHP的某些"神奇"方法/功能可能会过度保护PHP使其不考虑这些问题,但它们都不限于PHP。例如,我最近更新了一个脚本,该脚本使用array_search在已排序的数组上使用二进制搜索,并获得了预期的指数加速。
回答
首先遵循其他一些建议,例如进行概要分析和制定良好的资源分配决策,例如缓存。
另外,还要考虑外部资源(如数据库)的性能。例如,在MySQL中,我们可以检查慢查询日志。另外,请确保我们没有将数据库设计忘掉。针对真实数据优化查询(同样针对MySQL)可能会付出巨大的代价。
回答
我能想到的...
- 循环不变式始终是一个值得关注的好方法。
- 编写符合E_STRICT和E_NOTICE的代码,尤其是在记录错误时。
- 避免使用@运算符。
- require和include的绝对路径。
- 尽可能使用strpos,str_replace等代替正则表达式。
然后还有很多其他方法可能会起作用,但可能不会给我们带来很多好处。
回答
真正考虑使用XDebug分析器:它有助于检查某个功能相对于我们期望的执行量。
我尝试在适当的时候通过用数组查找替换逻辑来减少指令,同时提高代码的可读性。
这就是Jeff Atwood在[最佳代码根本没有代码] [1]中写的。
- 另外,请避免在另一个循环内循环,并嵌套if / else语句。
- 功能短。有时,当结果值已知时,不需要执行许多代码。
- 不必要的测试:
if (count($array) === 0) return;
也可以写成:
if (! $array) return;
消除了另一个函数调用! [1]:http://www.codinghorror.com/blog/archives/000878.html"最佳代码根本没有代码"
回答
包含文件的速度很慢,而要求它们甚至更慢。如果我们使用__autoload包含每个类,则将相加。例如。
我总是对在代码优化方面过于机灵的做法保持警惕,如果这样做会牺牲代码的精巧性。如果我们需要使代码变得晦涩难懂以使其快速运行,那么升级硬件而不是浪费时间尝试调整代码会不会便宜吗?毕竟,处理器周期比程序员周期便宜。
回答
Rasmus Lerdorf在FrOSCon '08上的最新演讲"简单就是困难"中给出了一些很好的技巧。如果我们正在使用字节码缓存(并且我们确实应该使用一个字节码缓存),那么包含路径未命中会带来很多麻烦,因此请优化require / require_once。