深入解析PHP类方法的执行原理与性能对比分析

百度工程师谈PHP函数的实现原理及性能分析

深入解析PHP类方法的执行原理与性能对比分析

类方法

类方法的执行原理与用户函数相同,也是翻译成操作码顺序调用。类的实现是由zend使用一个数据结构zend_class_entry来实现的,该结构存储了与类相关的一些基本信息。编译 PHP 时会处理此条目。

在zend_function的common中,有一个名为scope的成员,它指向当前方法对应的类的zend_class_entry。关于PHP中面向对象的实现,这里就不做更详细的介绍了。以后我会专门写一篇文章来详细介绍PHP中面向对象的实现原理。就函数而言,方法的实现原理与函数完全相同,其性能在理论上也类似。稍后我们会进行详细的性能对比。

性能对比

函数名称长度对性能的影响

》》测试方法比较名称长度为1、2、4、8、16的函数,测试比较它们每秒可以执行的次数,以确定函数名称长度对性能的影响。

》》测试结果如下图

》》结果分析

从图中可以看出,函数名的长度对性能还是有一定影响的。长度为 1 的函数和长度为 16 的空函数调用的性能差异为 1 倍。通过分析源码不难找到原因。上面提到,当一个函数被调用时,zend首先会在一个全局的function_table(一个哈希表)中通过函数名查询相关信息。不可避免地,名称越长,查询所需的时间就越长。因此,在实际编写程序时,建议多次调用的函数名称不要太长。

虽然函数名的长度对性能有一定的影响,但是具体是多大呢?这个问题还是要根据实际情况来考虑。如果一个功能本身比较复杂,对于整体性能不会有太大的影响。一种建议是,对于调用次数较多、功能相对简单的函数,给予简洁明了的名称。

函数数量对性能的影响

》》测试方法

在以下三种环境下进行函数调用测试并分析结果: 1. 程序仅包含 1 个函数 2. 程序包含 100 个函数 3. 程序包含 1000 个函数。测试这三种情况下每秒可以调用的函数数量

》》测试结果如下图

》》结果分析

从测试结果可以看出,这三种情况下的性能几乎是一样的。当函数数量增加时,性能下降很小,可以忽略不计。从实现原理分析,几种实现方式唯一的区别就是功能获取部分。前面说过,所有函数都放在一个哈希表中,不同数字下查找效率应该还是接近O(1)的,所以性能差异并不大。

不同类型函数调用的成本

》》测试方法

选择用户函数、类方法、静态方法和内置函数之一。函数本身不做任何事情,直接返回。主要测试空函数调用的消耗。测试结果是每秒执行的次数。为了消除测试过程中的其他影响,所有函数名称的长度相同。

》》测试结果如下图

》》结果分析

从测试结果可以看出,对于用户自己编写的PHP函数,无论是什么类型,效率都相差无几,都在280w/s左右。正如我们所料,即使是空调,内置功能的效率也高得多,达到了780w/s,是前者的三倍。可以看到,内置函数调用的开销还是比用户函数低很多。从前面的原理分析可以看出,主要差距在于调用用户函数时初始化符号表、接收参数等操作。

内置函数和用户函数的性能对比

》》测试方法

为了比较内置函数和用户函数的性能,这里我们选取几个常用的函数,然后使用PHP函数来实现相同的功能来比较性能。测试过程中,我们从字符串、数学、数组中分别选取了一个典型的进行比较。这些函数是字符串截取(substr)、十进制到二进制转换(decbin)、最小值(min)和返回。数组 (array_keys) 中的所有键。

》》测试结果如下图

》》结果分析

从测试结果可以看出,正如我们预期的那样,内置功能的整体性能远高于普通用户功能。尤其是涉及字符串操作的函数,差距达到1个数量级。因此,使用函数的一个原则是,如果某个函数有对应的内置函数,就尽量使用它,而不是自己编写PHP函数。对于一些涉及大量字符串操作的函数,为了提高性能,可以考虑使用扩展。例如常见的富文本过滤等。

与C函数性能比较

》》测试方法

我们选择了三个函数分别用于字符串操作和算术操作进行比较,并且PHP是使用扩展来实现的。这三个函数分别是简单的一次性算术运算、字符串比较和多重算术运算。除了两类功能外,我们还将测试去除空调开销功能后的性能。一方面,我们比较了两个函数(C和PHP内置)的性能差异,另一方面,我们验证了空调函数的消耗测试点:执行100,000次操作的时间消耗

》》测试结果如下图

》》结果分析

除去php函数空调的影响后,内置函数和C函数的开销差别很小。随着功能越来越复杂,双方的性能趋于一致。从前面的功能实现分析中可以很容易地证明这一点。毕竟内置函数都是用C实现的,函数越复杂,C和PHP的性能差距就越小。与C相比,PHP函数调用的开销要高很多,而且简单函数的性能还是有一定影响的。因此,PHP中的函数不应该嵌套和封装得太深。

伪函数及其性能

在PHP中,有一些函数是标准函数用法,但底层实现与真正的函数调用完全不同。这些功能不属于上述三个功能中的任何一个。它们的本质是单个操作码,这里称为伪函数或指令函数。

如上所述,伪函数的使用方式与标准函数一样,并且看起来具有相同的特征。但当它们最终执行时,会被zend反射成相应的指令(操作码)进行调用,因此它们的实现更接近于if、for、算术运算等操作。

》》php中的伪函数

伊塞特

空的

未设置

评估

从上面的介绍可以看出,由于伪函数是直接翻译成指令执行的,因此与普通函数相比,少了一份函数调用带来的开销,因此性能会更好。我们通过下面的测试来进行对比。 Array_key_exists和isset都可以判断数组中是否存在某个key。我们来看看他们的表现吧。

从图中可以看出,与array_key_exists相比,isset性能要高很多,基本上是前者的4倍左右,甚至与空函数调用相比,其性能也高出1倍左右。这也证明PHP函数调用的开销还是比较大的。

你可能想看:
« 上一篇
下一篇 »

相关推荐

php实时推送,php实地培训

2026年10月05日

55阅读

php乱码出现问号的原因,php乱码出现问号的原因有哪些

2026年10月05日

46阅读

php一句话木马,一句话木马ctf

2026年10月05日

49阅读

php获取数组长度,php中如何获取数组的长度

2026年10月05日

51阅读

php面试题库及答案,php程序员面试真题库

2026年10月05日

49阅读

phpcontent-type修改,php源码二次修改需要多少钱

2026年10月05日

44阅读