4 PHP与C性能对比分析
很多时候,大家发现PHP模块性能不行的时候,就来一句“ok,我们采用C重写吧”。在公司内,采用C/C++来写业务逻辑模块的现象到处都有,在前几年甚至几乎全部都是采用C来写。那时候大家写的真是一个痛苦:调试难、敏捷不要谈。
那么,本章节要谈论的一个话题就是:C写的业务逻辑和PHP写的业务逻辑模块进行性能对比,采用真实的数据来说话。
4.1前提
为什么要特别说出这个前提呢?因为在理想情况下,一个功能采用PHP实现,该性能铁定不可能比理想的C写出来好。这个前提需要特别注意。
但为什么还要对比呢?因为在现实情况下,能写出非常优秀的C程序,并且在频繁修改的情况下还能做到完全高性能的又有几个呢?并且在现实的应用中C实现的性能是否真的全都都比PHP要好好几倍呢?这些目前都没有确切的数据来论证。
所以,本章节的对比是基于现实中的情况来进行的,并采用真实数据来说话。
4.2 真实业务模块PHP模块 VS C模块
4.2.1业务模块介绍
一个真实的案列,该业务模块的流量高达数十亿。该模块的架构图如下:
图4、业务模块架构图
该业务模块功能非常简单,上层是web server,下游是各个数据模块。都是基于socket进行数据交互。该业务模块的主要工作模型是:响应web server的请求,根据请求从各个后端数据模块读取相应数据,并根据数据产出最终的HTML页面返回给web服务器。
为了方便后续介绍,定义CUI表示用C实现的模块,PHPUI表示用PHP实现的模块。
4.2.2C/C++模块的性能数据结果
09年,该模块重构选择了一个新的C/C++框架。当时重构的时候,该模块连接的后端数据模块规模在5-7个。
基于C/C++的模块,最终测试数据数据分成两个部分:
一、性能对比测试。
基于当时线上压力,进行真实数据的性能测试。所以当时只测试一个压力数据如下:
压力:210QPS
CPU(IDLE):84.18
二、极限性能测试1。
该测试模型是:CUI只连接一个核心数据模块,其他数据模块完全关闭。
三、极限性能测试2。
该测试模型是:CUI连接后端一个核心数据模块,3个数据模块,其他数据模块不连接。
测试后性能数据如下:
4.2.3 PHP实现模块的性能测试数据
到11年,基于09年的CUI基本上达到了代码不看维护的地步。而且这个时候,CUI的极限性能已经不到600QPS(主要原因是随着项目的发展,后端数据模块的数目增加到14个)。据此,决定采用PHP方案来重写整个模块,并产出最终的pbui模块。
性能测试结果分成两种:
1、PHPUI连接一个核心模块。测试数据如下:
图5、PHPUI性能测试结果1
2、PHPUI连接后端所有模块(14个)。测试性能数据如下:
图6、PHPUI性能测试结果2
4.2.4数据对比结论
由于PHPUI和CUI的业务逻辑和测试方法都不完全相同,所以抽取了部分大体能对比的点进行整理。具体对比数据如下:
从上面的对比数据来看,在真实的业务项目中,PHPUI的性能并不会比CUI差。这个不是简简单单一个模块来验证的,在部门里面,我们有不少模块都是从C/C++迁移到PHP,从迁移的结果来看,并没有存在质的性能下降,大部分模块迁移后性能指标都是非常接近的。
这个时候就需要思考为什么会这样了?细分来说有两个问题:
1、 为什么在真实业务项目中,PHPUI的性能并不会比CUI差太多?
2、 为什么基准的PHP性能这么高,80CPU的情况下2000QPS,但到了真实的PHP模块中只能是200QPS?
其实这两个问题,也可以归结成一种原因:在真实业务项目中,影响性能更多的不是说采用了什么语言,而是其业务相关的部分,比如说socket交互次数,比如说字符串处理,也比如说网络交互包大小。
OK。那么接下来的关键是找出影响性能的关键因素。
4.2.5影响PHP模块性能的关键因素
从前面分析,我们得出,影响前端PHP模块性能的关键因素不是语言本身(是否是PHP/JAVA/C都不重要)。那么到底影响PHP业务模块性能的关键因素在哪里呢?CPU耗时是统计一个项目性能的关键点之一,考虑到系统中都打印出了系列日志。通过分析日志中请求的耗时分布可以大体上看出关键点。
在我们系统中,CPU耗时重点打印出以下几个方面:
1、 请求总时间。
2、 请求关键函数的性能,其中所有的socket交互都有耗时计算。
3、 模版渲染也是好事的一个关键点。
在前面分析中,我们基本上判定socket和字符串处理是一个关键点之一,通过数据我们来验证下。抽取一个模块指定数目的日志,进行综合分析得出以下数据:
通过这个可以看出,在一个业务模块中,影响最大的是socket数据交互,其次是大量的字符串处理。具体细分来说是以下几个因素:socket交互次数、socket交互包大小、socket交互响应时间、字符串处理。
4.2.6结论
通过上述分析,可以得出以下结论:在前端业务模块中,PHP语言本身不会成为性能瓶颈。因为影响性能的几个关键因数是:
● 网络交互数目。
● 网络交互数据大小,包含数据打包解包开销。
● 网络交互响应时间。
● 大量的字符串处理。
5最终结论
通过上述三个章节的具体分析,可以得出以下结论:
1、从PHP实现原理来看,PHP属于半编译型语言,并且在各个方面都进行了大量的优化工作,本身不会存在明显的性能问题。但由于动态语言的特性,决定了PHP需要运行在Zend Engine虚拟机上,并且在变量查找、函数调用、作用域切换等各个方面需要一些额外开销。
2、从PHP的基准性能来看,PHP本身不会存在明显的资源消耗,单机QPS能够轻松过W, PHP框架本身也不会对业务系统的性能带来关键性的影响。
3、从真实的应用场景来看,基于C语言实现的模块不见得比基于PHP实现的模块性能高效很多。因为在真实的应用场景中,更多的性能开销在于网络数据交互和字符串处理。语言方面微小的性能差异不会成为瓶颈。
据此,可以推出:基于C语言实现的大部分业务系统都可以考虑迁移到PHP上来,一方面能够快速开发,另外一方面性能也不会存在问题。
最后,关于影响PHP性能的关键因素的具体分析和关于语言函数级别PHP与C的基准性能对比分析,请关注下文《深入探讨PHP性能问题》。
原文:http://stblog.baidu-tech.com/?p=1343
PHP之友评论