PHP 性能分析与实验——性能的宏观分析
moboyou 2025-07-16 04:09 4 浏览
对 PHP 性能的分析,我们从两个层面着手,把这篇文章也分成了两个部分,一个是宏观层面,所谓宏观层面,就是 PHP 语言本身和环境层面,一个是应用层面,就是语法和使用规则的层面,不过不仅探讨规则,更辅助以示例的分析。
宏观层面,也就是对 PHP 语言本身的性能分析又分为三个方面:
PHP 作为解释性语言性能有其天然的缺陷
PHP 作为动态类型语言在性能上也有提升的空间
当下主流 PHP 版本本身语言引擎性能
一、PHP 作为解释性语言的性能分析与提升
PHP 作为一门脚本语言,也是解释性语言,是其天然性能受限的原因,因为同编译型语言在运行之前编译成二进制代码不同,解释性语言在每一次运行都面对原始脚本的输入、解析、编译,然后执行。如下是 PHP 作为解释性语言的执行过程。
如上所示,从上图可以看到,每一次运行,都需要经历三个解析、编译、运行三个过程。
那优化的点在哪里呢?可以想见,只要代码文件确定,解析到编译这一步都是确定的,因为文件已不再变化,而执行,则由于输入参数的不同而不同。在性能优化的世界里,至上绝招就是在获得同样结果的情况下,减少操作,这就是大名鼎鼎的缓存。缓存无处不在,缓存也是性能优化的杀手锏。于是乎 OpCode 缓存这一招就出现了,只有第一次需要解析和编译,而在后面的执行中,直接由脚本到 Opcode,从而实现了性能提速。执行流程如下图所示:
相对每一次解析、编译,读到脚本之后,直接从缓存读取字节码的效率会有大幅度的提升,提升幅度到底有多大呢?
我们来做一个没有 Opcode 缓存的实验。20 个并发,总共 10000 次请求没有经过 opcode 缓存的请求,,得到如下结果:
其次,我们在服务器上打开 Opcode 缓存。要想实现 opcode 缓存,只需要安装 APC、Zend OPCache、eAccelerator 扩展即可,即使安装了多个,也只启用其中一个。注意的是,修改了 php.ini 配置之后,需要重新加载 php-fpm 的配置。
这里分别启用 APC 和 Zend OPCache 做实验。启用 APC 的版本。
可以看到,速度有了较大幅度的提升,原来每个请求 110ms,每秒处理请求 182 个,启用了 APC 之后 68ms,每秒处理请求 294 个,提升速度将近 40%。
在启用了 Zend Opcache 的版本中,得到同 APC 大致相当的结果。每秒处理请求 291 个,每请求耗时 68.5ms。
从上面的这个实验可以看到,所用的测试页面,有 40ms 以上的时间花在了语法解析和编译这两项上。通过将这两个操作缓存,可以将这个处理过程的速度大大提升。
这里附加补充一下,OpCode 到底是什么东东,OpCode 编译之后的字节码,我们可以使用bytekit 这样的工具,或者使用 vld PHP 扩展来实现对 PHP 的代码编译。如下是 vld 插件解析代码的运行结果。
可以看到每一行代码被编译成相应的 OpCode 的输出。
二、PHP 作为动态类型语言的性能分析与改进
第二个是 PHP 语言是动态类型的语言,动态类型的语言本身由于涉及到在内存中的类型推断,比如在 PHP 中,两个整数相加,我们能得到整数值,一个整数和一个字符串相加,甚至两个字符串相加,都变成整数相加。而字符串和任何类型连接操作都成了字符串。
<?php$a = 10.11;$b = "30";
var_dump($a+$b);
var_dump("10"+$b);
var_dump(10+"20");
var_dump("10"+"20");
运行结果如下:
float(40.11)int(40)int(30)int(30)
语言的动态类型为开发者提供了方便,语言本身则会因为动态类型而降低效率。在 Swift 中,有一个特性叫类型推断,我们可以看看类型推断会带来多大的一个效率上的差别呢?对于需要类型推断与不需要类型推断两段 Swift 代码,我们尝试编译一下看看效果如何。
第一段代码如下:
这是一段 Swift 代码,字典只有 14 个键值对,这段代码的编译,9 分钟了还没有编译完成(5G 内存,2.4GHz CPU),编译环境为 Swift 1.2,Xcode 6.4。
但是如果调整代码如下:
也就是加上了类型限定,避免了 planeLocation 的类型推断。编译过程花了 2S 。
可见,作为动态类型附加的类型推断操作极大地降低了程序的编译速度。
当然,这个例子有点极端,用 Swift 来类比 PHP 也不一定合适,因为 Swift 语言本身也还在不断的进化过程中。本例子只是表明在编程语言中,如果是动态类型语言,就涉及到对动态类型的处理,从编译的角度讲是会受影响的。
那么作为动态类型的 PHP 的效率如何提升呢?从 PHP 语言本身这个层面是没有办法解决的,因为你怎么写也是动态类型的代码。解决办法就是将PHP转化为静态类型的表示,也就是做成扩展,可以看到,鸟哥的很多项目,比如 Yaf 框架,都是做成了扩展的,当然这也是由于鸟哥是 C 高手。扩展由于是 C 或者 C++ 而写,所以不再是动态类型,又加之是编译好的,而 C 语言本身的效率也会提升很多。所以效率会大幅度提高。
下面我们来看一段代码,这段代码,只是实现了简单的素数运算,能计算指定值以内的素数个数,用的是普通的筛选法。现在看看扩展实现,跟 PHP 原生实现的效率差别,这个差别当然,不仅仅是动态类型和编译类型的差别,还有语言效率的差别。
首先是用纯 PHP 写成的算法,计算 1000 万以内的素数个数,耗时在 33s 上下,实验了三次,得到的结果基本相同。
其次,我们将这个求素数个数的过程,编写成了 PHP 扩展,在扩展中实现了 get_prime_numbers 函数,输入一个整数,返回小于该整数的素数。得到的结果如下,这个效率的提升是非常惊人的,在 1.4s 上下即返回。速度提升 20 倍以上。
可以想见,静态和编译类型的语言,其效率得到了惊人的提升。本程序的 C 语言代码如下:
PHP_FUNCTION(get_prime_numbers)
{ long value; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &value) == FAILURE) { return;
} int *numbers = (int *)malloc(sizeof(int)*128*10000); memset(numbers, 0x0, 128*10000); int num = 2;
numbers[0] = 2;
numbers[1] = 3; bool flag = true; double f = 0; int i = 0; int j = 0; for(i=5; i<=value; i+=2)
{
flag = true;
f = sqrt(i); for(j=0; j<num;j++)
{ if(i%numbers[j]==0)
{
flag = false; break;
} if(numbers[j]>f)
{ break;
}
} if(flag)
{
numbers[num] = i;
num++;
}
} free(numbers);
RETURN_LONG(num);
}
三、PHP 语言本身底层性能引擎提升
第三个性能优化层面是语言本身的性能提升,这个就不是我们普通开发者所能做的了。在 PHP 7以前,寄希望于小版本的改进,但是改进幅度不是非常的显著,比如 PHP 5.3 、PHP 5.4、PHP 5.5、PHP 5.5 对同一段代码的性能比较,有一定程度的进步。
PHP 5.3 的版本在上面的例子中已讲过,需要 33s 左右的时间,我们现在来看别的PHP版本。分别运行如下:
PHP 5.4 版,相较 5.3 版已经有一定程度的提升。快 6 秒左右。
PHP 5.5 版在 PHP 5.4的基础上又进了一步,快了 6S。
PHP5.6 反而有些退步。
PHP 7 果真是效率提升惊人,是 PHP5.3 的 3 倍以上。
以上是求素数脚本在各个 PHP 版本之间的运行速度区别,尽管只测试了这一个程序,也不是特别的严谨,但是这是在同一台机器上,而且编译 configure 参数也基本一样,还是有一定可比性的。
在宏观层面,除了上面的这些之外,在实际的部署过程中,对 PHP 性能的优化,还体现为要减少在运行中所消耗的资源。所以 FastCGI 模式和 mod_php 的模式比传统的 CGI 模式也更为受欢迎。因为在传统的 CGI 模式中,在每一次脚本运行都需要加载所有的模块。而在程序运行完成了之后,也要释放模块资源。如下图所示:
而在 FastCGI 和 mod_php 模式中,则不需要如此。只有 php-fpm 或者 Apache 启动的时候,需要加载一次所有的模块,在具体的某次运行过程中,并不需要再次加载和释放相关的模块资源。
相关推荐
- 都说PHP性能差,但PHP性能真的差吗?
-
今天本能是想测试一个PDO持久化,会不会带来会话混乱的问题先贴一下PHP代码,代码丑了点,但是坚持能run就行,反正就是做个测试。<?php$dsn='mysql:host=l...
- PHP 性能分析与实验——性能的宏观分析
-
对PHP性能的分析,我们从两个层面着手,把这篇文章也分成了两个部分,一个是宏观层面,所谓宏观层面,就是PHP语言本身和环境层面,一个是应用层面,就是语法和使用规则的层面,不过不仅探讨规则,更辅...
- 深入浅出之JWT(JSON Web Token)(深入浅出之类的词语)
-
什么是JWT?JWT是JSONWebToken的缩写,它是一种开源标准(RFC7519),用来定义通信双方如何安全地交换信息的格式。本身定义比较简单,结合实践经验,我总结了几点能够更好地帮助理解...
- PHP的Cookie使用详解(php cookbook)
-
什么是CookieCookie是保存在浏览器端的一些数据,是http协议的一部分,一般用于保存用户的登录信息,当浏览器发送http请求时,会将Cookie封装在http协议的头信息中,和其他数据一块儿...
- PHP8中获取并删除数组中第一个元素-PHP8知识详解
-
我在上一节关于数组的教程,讲的是在php8中获取并删除数组中最后一个元素,今天分享的是相反的:PHP8中获取并删除数组中第一个元素。回顾一下昨天的知识,array_pop()函数将返回数组的最后一个元...
- 从PHP开始学渗透 -- GET请求和POST请求
-
成年人只管利益,小孩子才分对错。。。----网易云热评一、GET请求1、get可以理解为一个系统定义好的数组2、通过var_dump看一下GET的类型,浏览器访问网址,后面加上"?aiyo...
- 黑客不会告诉你的10个Linux渗透测试工具
-
凌晨两点,我盯着目标企业的边界防火墙日志——所有端口都被封禁,IDS(入侵检测系统)警报安静得诡异。正当我以为这是一场“不可能完成”的渗透测试时,搭档发来一条消息:“试试LinPEAS,你可能会发现惊...
- Facebook 前端技术栈重构分享(facebook的技术)
-
作者:@AshleyWatkins,RoyiHagigi译者:阿里@张克军转发连接:https://www.yuque.com/docs/share/6aee9dd5-da3f-462b-b4b...
- 平滑升级!一文掌握CSS过渡与动画属性,让你的网页动起来!
-
“这里是云端源想IT,帮你轻松学IT”嗨~今天的你过得还好吗?找一颗属于你自己的星星吧它会给你指引方向一直到天明-2024.04.12-在网页设计中,动画效果是吸引用户眼球的重要手段。CSS动画...
- 如何在前端通过JavaScript创建修改CAD图形
-
背景在之前的博文CAD图DWG解析WebGIS可视化技术分析总结、CAD_DWG图Web可视化一站式解决方案-唯杰地图-vjmap中讲解了如何把CAD的DWG格式的图纸Web可视化的方案,那在Web前...
- 零基础教你学前端——47、SVG绘制路径
-
在SVG中,使用path标签来定义一个路径。它是一个单标签,基本语法为:尖角号path,斜线尖角号。应用路径,我们可以绘制任意形状的图形。path标签的重要属性d,用来定义绘制路径的命令,d...
- 回流焊温度曲线知识讲解(回流焊温度曲线图讲解)
-
回流焊温度曲线知识讲解回流焊在业内俗称炉子,按类型分有普通空气炉,氮气炉、真空炉,普通的产品用空气炉,对气泡率要求低的则需要选择氮气炉或真空炉,一般这些都是高端产品,集中在航空航天、半导体、军工等对品...
- MFC转QT:Qt高级特性 - 样式表(qt页面切换的样式)
-
Qt样式表概述Qt样式表(QtStyleSheets)是基于CSS的样式系统,允许开发者以类似于Web前端的方式定制Qt应用程序的外观。这一特性极大地简化了Qt应用的界面定制,提供了比MFC更强大...
- 详解CSS3中的动画效果:从基础到进阶实战
-
引言CSS3引入了强大的动画功能,使得开发者能够在不依赖JavaScript的情况下创建丰富的视觉动效。本文将深入探讨CSS3动画的核心概念、主要特性以及如何通过关键帧动画和过渡效果实现各类动画效果。...
- 只会柱状图、饼状图、折线图怎么行,来用Python画个热力图
-
花花世界迷人眼,东西太多不知选?万物存在即合理,不知根本,难得善法。术业有专攻,凡事不能蛮干,不知怎么画热力图,请往下看。第一步:安装并导入相关包主要用到了pandas和pyecharts这两个包,p...
- 一周热门
- 最近发表
- 标签列表
-
- 外键约束 oracle (36)
- oracle的row number (32)
- 唯一索引 oracle (34)
- oracle in 表变量 (28)
- oracle导出dmp导出 (28)
- oracle两个表 (20)
- oracle 数据库 字符集 (20)
- oracle安装补丁 (19)
- matlab化简多项式 (20)
- 多线程的创建方式 (29)
- 多线程 python (30)
- java多线程并发处理 (32)
- 宏程序代码一览表 (35)
- c++需要学多久 (25)
- css class选择器用法 (25)
- css样式引入 (30)
- html5和css3新特性 (19)
- css教程文字移动 (33)
- php简单源码 (36)
- php个人中心源码 (25)
- 网站管理平台php源码 (19)
- php小说爬取源码 (23)
- github好玩的php项目 (18)
- 云电脑app源码 (22)
- html画折线图 (24)