如何让PHP性能问题再也不饱受诟病

PHP做为Web开发中应用最普遍的开源脚本语言,凭借库类丰富,使用简单,安全等特色,成为Facebook和BAT等互联网巨头和全球超过70%网站的主要开发语言,然而性能问题是PHP一直以来饱受诟病的,来自PHP/PECL开发组的高驰涛同窗将为咱们带来他对PHP性能优化方面的思考和建议。
Xxxphp

本期主讲:高驰涛,Neeke Gao,PHP/PECL开发组成员,同时是SeasLog,JsonNet-PHP的做者,目前在云智慧担任架构师。
今天主要从PHP的发展和性能优化历史,来谈PHP语言在性能优化方面所作过的努力,以及咱们的一些研究成果。
谈起PHP,咱们先来了解几个数字:
Xxx数组

1995年, PHP发布了第一个版本,这要感谢PHP之父Rasmus Lerdorf的辛苦努力。PHP在问世之初是Personal Home Page的缩写,那时候只是被看成制做我的网页的一门简单语言;后来随着互联网的发展以及开源社区的贡献,PHP逐步成长成为一门被普遍应用的高级语言,其英文含义也进化为PHP: Hypertext Preprocessor,即超级文本预处理语言。缓存

官方统计数字显示,全球排名前1000万的网站应用中,有81.9%是使用PHP语言开发的。并且,天天有416个新增PHP网站进入全球前1000万排名,数量还在不断增长。发展到今天,PHP经历了4,5,7几个很是重大的版本迭代,最新的release版本是7.0.6。在二十多年的发展过程当中,应用最普遍的PHP版本是PHP 5,同时也是目前全球互联网上应用最为普遍的一个语言版本。安全

为何没有PHP6,而是直接从PHP5到PHP7,这里面有一个小故事。目前的PHP5.6,其实就是原预计发布的PHP6,但因为各项改动不足以支撑一个全新的PHP分支,组织内投票没有经过发布,而最终做为了PHP5.6进行发布。性能优化

PHP7又称为PHP NG,即“PHP Next Generation(下一代PHP)”,在性能和稳定性方面作了很是大的提高。为何这么说呢,要从PHP的业务模型提及。架构

一、PHP Transaction Module业务模型
下面我先带你们过一下PHP5几个重大版本改动中的性能优化点,下面这张图是PHP整个运行过程当中的几个关键点。
Xxx运维

在PHP运行过程当中,在Script Entry接收到请求以后。
首先通过语法解析器(Parser),此时会抛出一些致命的语法错误或警告(后续的版本改动中,会有一些致命错误转换为exception抛出);
其次通过编译器(Compiler),这部份内容中会进行更高级的解析,并测试将PHP高级语言编译成OpCode;工具

而后交给Execute进行执行;执行过程当中发现有新的文件或类被引入,会再进行Compiler,往复执行。性能

从这里能够看出,其实PHP也是“编译型”语言,只不过是每次请求都编译,或称动态编译。那么,后续的优化过程当中就能够进行针对性优化,即:将编译后的内容缓存起来,直接执行,以节省编译时间。开发工具

了解一点PHP的同窗都知道,PHP一般被认为是简单、低效,这并非没有道理。咱们来看一段PHP源码,从而向你们解释为何“简单”,为何“低效”。
Xxx

这段结构是PHP5及之前版本中全部变量和方法执行的核心,这是通用的变量存储结构。能够看到,同一个变量可以同时有多个属性,或long,或double,或char,或int,或array,或Object。这给工程师以充分的自由度,一样的一个数字,或字符串,不须要预设类型,就能够直接生成并使用。这就是为何“简单”,这是对工程师来讲的。

而同时丢给Zend引擎(解析执行引擎)的,有着大量的负担,由于须要引擎在每一次使用或运算时,都要不停的判断类型到底是什么类型属性。这就是为何“低效”的一个最直接缘由。

二、PHP Performance Difficulty 性能之坑
对于一个使用PHP开发的应用来讲,通过大量的实践,能够总结出4个最影响性能的点:
图片描述

IO, Memory, CPU, NetWork,是否是很是眼熟?没错,这其实并不仅仅是PHP语言的性能瓶颈,任何一门语言,或者就目前咱们所处的世界中,凡是使用计算机语言开发的服务或应用,都存在这4个瓶颈。

三、Optimize from PHP5 to PHP7 优化之旅
下面就为你们介绍一下PHP5围绕以上4个点所作的一些性能优化。在聊具体的性能优化方法以前,咱们能够抛开以前的知识储备,打开脑洞,发散思惟,思考应该如何入手。每一个人的想法彻底不同,个人想法是这样的:

会不会是PHP自己的运行模型(或业务模型)或者Zend引擎设计存在问题?
有没有可能将PHP语言在发布运行以前进行预编译,把它转变成Bytecode?
有没有可能经过一种解析器把PHP转变成C或C++语言,而后进行make或build?
能不能开发另外一套解析运行引擎?
会不会出现另外一套彻底不同的运行模型(或业务模型)?
等等。

这些想法在PHP社区内家常便饭,并不只仅是我一我的在这么想,很是多PHP资深专家也在思考,并且在各个方向上都有一些开源的工具或服务发布了。因为PHP5有很是多版本,这里咱们仅就应用最广的PHP5.4和PHP5.5-5.6版原本简要说明性能优化的几个点。
图片描述
PHP5.4 最主要的性能改进是在数组的生成和应用上面,一个简单的延后分配节省了很是大量的内存,由于多数状况数组在直接引用上并不进行运算,从而并不进行内存创建与分配工做。另外,PHP5.4在运行时中添加了Literal Table和Binding Cache操做,这两个改动相对上面延后分配内存是更复杂一些的,它在运行过程当中节省了大量的CPU运算。
图片描述

PHP5.5及5.6放在一块儿来讲,由于它们真的很像,并且在目前PHP5整个大分支的维护过程当中,通常是在PHP5.5上进行,而后把相关修改向5.6同步。5.5和5.6最重要的一个性能改进,是使用了编译Cache。前面咱们了解了PHP的运行过程当中会存在“编译->OpCode->执行”的过程,而将编译结果缓存起来是一个重要的性能优化点,OpCache就是作这个工做的。OpCache今后进入了PHP的内核,而再也不是一个第三方扩展。

同时Zend引擎还有一样一个Cache优化扩展版本产生,即Zend O+,能够认为是Zend的Plus版本,在内存和CPU上,都作了一些改进。
图片描述

最后来看看PHP7的几个优化点:PHP7直接修改了Zend Zval结构,这算得上是一个很大改动。同时在PHP7中,数组的结构也变得更加的不同,这又是一个伤筋动骨的改动。官方数据中PHP7较PHP5.6有近两倍的性能提高,主要就集中在这两个点上。
看一下PHP源码:
图片描述
在一个Zval结构中,一个变量仍然能够属于各类类型的,但在使用的时候,能够快速判断是哪一种类型,由于不一样的类型会存储在不一样的指针中;并且内存使用也因为不一样的指针类型而大量地下降;因为内存使用大量下降,从而为CPU更快地寻址和操做带来了更好的可能性。因此有了Zval的结构变更带来35%性能提高的结论。
图片描述

同一个数组,在PHP5中的内存使用是跳跃不连贯的,而在PHP7中是连续有序的,这使得内存使用和CPU使用都更加地高效,数组的结构变更,给PHP7带来了接近50%的性能提高。
四、PHP Performance Tools 工具推荐

前面在咱们发散思惟时列举了不少PHP性能优化的点,几个开源社区中已经发布过针对这些的优化工具,给你们推荐一些:
Facebook发布的HHVM:
图片描述

HHVM (HipHop Virtual Machine)相似于C#的CLR和Java的JVM,会将PHP代码转换成高级别的字节码(一般称为中间语言),而后在运行时经过即时(JIT)编译器将这些字节码转换为x64的机器码。
下面是一些在开发调试过程当中常用的工具和软件服务:
图片描述
图片描述
此类开发工具和服务不少,能够为开发者和运维同窗节省大量的定位和解决问题时间。
以我开发的SeasLog为例,因为使用内存buffer/批量IO,替代直接IO,能够直接为服务的QPS能力提高带来强劲动力,下图是SeasLog和log4php的性能对比:
图片描述最后为东家打个小广告,云智慧的APM应用性能管理产品透视宝www.toushibao.com,能够提供更为强劲的性能管理分析的商业支持方案,目前支持包括PHP,Java,DotNet,Python,IOS,Android在内各类主流应用的性能监测和管理分析能力,欢迎你们交流体验。

相关文章
相关标签/搜索