PHP7相对于PHP5提升了将近一倍的性能,下面我将针对PHP7与PHP5的变量结构实现进行对比,分析为什么PHP7性能提升。当然变量结构修改只是PHP7性能提升中的一部分原因,还有很多原因比如HashTable结构变更、减少内存分配次数、多使用栈内存等等,本文只对变量结构进行分析。

本文源码基于PHP7.2.3以及PHP5.6.34

PHP作为弱类型语言,所有变量都是zval结构体来保存,PHP7与PHP5的zval结构也不相同,下面将分析两者zval结构的不同之处。

PHP5

PHP5的zval定义于Zend\zend.h

typedef struct _zval_struct zval; //此段代码在Zend\zend_types.h中

...

typedef union _zvalue_value {

long lval;/* long value */

double dval;/* double value */

struct {

char *val;

int len;

} str;

HashTable *ht; /* hash table value */

zend_object_value obj;

zend_ast *ast;

} zvalue_value;

struct _zval_struct {

/* Variable information */

zvalue_value value; /* value */

zend_uint refcount__gc;

zend_uchar type; /* active type */

zend_uchar is_ref__gc;

};

可以看到zval结构体有四个成员:

zvalue_value:共用体,储存变量的值

refcount__gc:引用计数,用于垃圾回收,默认值1

type:变量的具体类型

is_ref__gc:是否引用,用于垃圾回收,默认值0

zvalue_value共用体用来储存变量的值:

long lval成员用于储存整型与布尔型。

double dval成员用于储存 浮点型。

结构体str用于存储字符串,之所以使用结构体是用来储存字符串的长度,实时获取字符串的长度的时间复杂度是O(n),在PHP中字符串的操作非常频繁,这样能节省大量的时间。

HashTable *ht用来存储数组,PHP中的数组非常强大,这一切都基于哈希表结构。

zend_object_value obj用来存储对象。在面向对象编程中,这也是非常重要的一部分。

zend_ast *ast zend抽象语法树,zend内核使用。

zval结构体中的type成员有以下几种类型(代码位于Zend\zend.h):

/* data types */

/* All data types <= IS_BOOL have their constructor/destructors skipped */

#define IS_NULL 0 #define IS_LONG 1 #define IS_DOUBLE 2 #define IS_BOOL 3 #define IS_ARRAY 4 #define IS_OBJECT 5 #define IS_STRING 6 #define IS_RESOURCE 7 #define IS_CONSTANT 8 #define IS_CONSTANT_AST 9 #define IS_CALLABLE 10

PHP7

PHP7的zval定义于Zend\zend_types.h

typedef struct _zval_struct zval;

...

typedef union _zend_value {

zend_long lval;/* long value */

double dval;/* double value */

zend_refcounted *counted;

zend_string *str;

zend_array *arr;

zend_object *obj;

zend_resource *res;

zend_reference *ref;

zend_ast_ref *ast;

zval *zv;

void *ptr;

zend_class_entry *ce;

zend_function *func;

struct {

uint32_t w1;

uint32_t w2;

} ww;

} zend_value;

struct _zval_struct {

zend_value value;/* value */

union {

struct {

ZEND_ENDIAN_LOHI_4(

zend_uchar type,/* active type */

zend_uchar type_flags,

zend_uchar const_flags,

zend_uchar reserved) /* call info for EX(This) */

} v;

uint32_t type_info;

} u1;

union {

uint32_t next; /* hash collision chain */

uint32_t cache_slot; /* literal cache slot */

uint32_t lineno; /* line number (for ast nodes) */

uint32_t num_args; /* arguments number for EX(This) */

uint32_t fe_pos; /* foreach position */

uint32_t fe_iter_idx; /* foreach iterator index */

uint32_t access_flags; /* class constant access flags */

uint32_t property_guard; /* single property guard */

uint32_t extra; /* not further specified */

} u2;

};

可以看到PHP7的代码相对PHP5的代码更加符合规范,所以更便于理解。

在_zval_struct结构体中:

zend_value共用体用于储存变量的值

u1共用体,用于存储变量的类型,以及一些辅助值

u2共用体,辅助值,由于内存对齐,_zval_struct结构体总共16字节大小,zend_value为8字节,u1为4字节,剩下的4字节防止浪费,用来作为辅助值,具体辅助用来干嘛代码的注释已经说明了。

u2共用体的辅助值成员一直在增加,我记得当时PHP7刚发布的时候才4个辅助值,现在已经9个了。

zend_value共用体就不用解释了,相比PHP5,PHP7的代码结构更加清晰、规范,一眼就能看出共用体的成员都用来储存什么类型的数据,我们可以发现PHP7 zend_value共用体大部分数据都是存储的指针,由于指针占的内存小,所以PHP7的zend_value占的内存比PHP5的zend_value要小。

对比

我们可以看到虽然PHP7的变量结构看起来更复杂,但是由于使用共用体,所以其实内存占用并不多,PHP5中的zval占用24个字节,PHP7中的zval占用16个字节。内存占用减少了1/3,而且PHP中的代码逻辑都是基于变量来实现的,所以对性能的影响非常大。可以看到PHP7中的代码规范比PHP5好了很多,并且PHP7的变量结构中辅助值的使用充分利用了内存,同时提高了性能。

结语

PHP7主要是优化性能,其实这个和互联网的发展也有关系。在之前,访问量和性能并不是最主要的,PHP凭借敏捷开发能在编程语言中占据一席之地。然而随着互联网的发展,网民数量的增多,以及各种编程语言的出现,大多数大型网站追求的是高并发以及访问速度,这个时候PHP的劣势就展示出来了。当然可以感受到PHP社区对这门语言的热情,包括PHP7的性能提升,swoole扩展的流行,以及正在开发中的PHP JIT版本,相信PHP会发展的越来越好。

php7 变量,PHP7变量结构分析相关推荐

  1. C++ 笔记(05)— 变量(变量定义、声明、初始化、extern关键字、变量之间转换)

    1. 变量定义 变量定义就是告诉编译器在何处创建变量的存储,以及如何创建变量的存储.变量定义指定一个数据类型,并包含了该类型的一个或多个变量的列表,如下所示: type variable_list; ...

  2. linux快捷键 赋值,2_Shell语言———bash的快捷键、变量声明、引用变量及变量替换...

    一.初识bash Bash是一种解释型语言,但它也提供了交互式接口,支持变量,因此提供了编程环境,所以可以称bash为程序语言. 解释型语言属于弱类型语言,其特点为: 1.它不强制区分变量类型,即无论 ...

  3. linux脚本查看变量类型,Shell变量:Shell变量的定义、删除变量、只读变量、变量类型...

    变量是任何一种编程语言都必不可少的组成部分,变量用来存放各种数据.脚本语言在定义变量时通常不需要指明类型,直接赋值就可以,Shell 变量也遵循这个规则. 在 Bash shell 中,每一个变量的值 ...

  4. shell脚本——系统变量 与 变量(定义 使用 只读 删除)

    shell常见的系统变量的解析 我们可以在执行 Shell 脚本时,向脚本传递参数,脚本内获取参数的格式为:$n.n 代表一个数字,1 为执行脚本的第一个参数,2 为执行脚本的第二个参数,以此类推-- ...

  5. 【C 语言】变量本质 ( 变量概念 | 变量本质 - 内存空间别名 | 变量存储位置 - 代码区 | 变量三要素 )

    文章目录 一.变量概念 二.变量本质 1.变量本质 - 内存别名 2.变量存储位置 - 代码区 3.变量三要素 一.变量概念 变量概念 : 变量 是 既能读 , 又能写 的 内存对象 ; 与 变量 相 ...

  6. 【MATLAB】变量 ( 变量引入 | 变量类型 )

    文章目录 一.变量引入 ( ans 默认变量 ) 二.变量类型 一.变量引入 ( ans 默认变量 ) 使用 matlab 代码编写如下公式时 , 公式层级很多 , 很复杂 , 需要很多括号进行优先级 ...

  7. torch 变量_python变量

    ⽬目标 变量量的作⽤用定义变量量认识数据类型 ⼀一. 变量量的作⽤用 举例例体验:我们去图书馆读书,怎么样快速找到⾃自⼰己想要的书籍呢?是不不是管理理员提前将书放到固定位置,并把这个位置进⾏行行了了编 ...

  8. 如何在php7.2/php7.3中安装mcrypt扩展?

    mcrypt 是php里面重要的加密支持扩展库,linux环境下该库在默认情况下不开启.window环境下,PHP>=5.3,默认开启mcrypt扩展.mcrypt扩展是mcrypt加密库的接口 ...

  9. bash脚本编程之一 变量、变量类型等

    变量的内容 1.变量命名:            1.只能包含字母.数字和下划线,并且不能以数字开头,     2.不应该跟系统中已有的环境变量重名     3.最好能见名知意 2.变量赋值: 设置变 ...

  10. ext如何将值存入变量_变量类型之值类型与引用类型

    前言 变量类型在我们日常开发中经常接触到,但是js中的变量类型与其他强类型语言不同,由于js是弱类型语言,因此他的变量拷贝在我们实际的日常开发中有很多需要注意的项.而半斤在最近的开发中遇到了很多匪夷所 ...

最新文章

  1. SQL Server误区30日谈-Day26-SQL Server中存在真正的“事务嵌套”
  2. Oracle 12C -- sequence的新特性-会话序列
  3. 机器学习实战(十一)利用PCA来简化数据
  4. Linux内核【链表】整理笔记(1)
  5. React.js及React Native知识及实践
  6. Python堆叠式神经网络模型实践【Stacking策略+Keras框架】,GUI可视化应用
  7. 微星电脑win、ctrl等组合键时而失灵
  8. 计算机组成原理疑难知识点
  9. Java移位运算符原来这么简单
  10. java获取jsessionid后_关于jsessionid获取的问题
  11. PowerDesigner将PDM导出生成WORD文档(rtf文档)
  12. 一次基于Vue的Vedio.js使用
  13. 苹果测试软件testflight游戏,教程:如何使用TestFlight 参与App 测试
  14. C++十一月月末总结
  15. 提高Java开发效率:5个常用的Visual Studio代码扩展工具
  16. IT业狼多肉少?程序员的绝地求生,谁能给他们一把“98K”?
  17. vue 下载文件流和捕获后端返回的状态码和错误信息的方法
  18. GPS天线类型和特点
  19. SecureCRT常用的几个命令
  20. 无炫技:纯粹的Bert和Roberta

热门文章

  1. 软件工程网络15个人阅读作业1(201521123029 郑佳明)
  2. XidianOJ 1195 Industry of Orz Pandas
  3. 在ACCESS中使用Group By语句
  4. 一场关于Google不作恶信条的辩论会
  5. 牛客15499 Jxc军训(快速幂,逆元)
  6. Python程序生成.exe的可执行文件
  7. %dn在c语言中是什么意思,请问C语言中 char far 是什么意思?
  8. 客户机服务器文件更新,服务端数据更新,如何更新客户端缓存
  9. python的pillow给图片加文字_Python-Pillow库给图片添加文字、水印
  10. win10调节屏幕亮度_自动调节电脑屏幕亮度软件,保护你的眼睛