神奇的PHP7

PHP7从正式问世到现在,算起来也有两年多了,开启了PHP的新里程,新架构,新思想。带来大幅的性能改进和新的特性,以及改进一些过时功能,移除一些就特性。

现在官网是已经更新到php7.2 RC5版本了,之前的旧版本主要讲究的是开发效率快,但是性能不是非常好,而php7主要就是追求高性能,侧重性能优化。在计算密集型的开发时,其性能极其低劣,远不如C/C++、java等语言。

如果PHP可以提升性能,将可以节约大量的服务器资源。Facebook就重写了PHP引擎HHVM,这是他们自己重写的,不是PHP官方的引擎。他们这样的目的就是提升性能,经实际测试,这性能提升了70%,这意味着性能已经大幅度地优化了。PHP官方重写了ZendVM,性能比PHP5.6提升了近300%,这在wordpress已经得到了证实,qps达到了311,性能几乎达到了2倍。如图:


  • 错误异常
在以前PHP程序出错后,zend引擎就会发生致命错误,终止程序运行。而现在PHP7就可以用try/catch捕获错误了。

try {
  non_exists_func();
} catch(EngineException $e) {
  echo “Exception: {$e->getMessage();}\n”;
}

  • 使用zval内存(ZVAL结构的重构)
在zend引擎和扩展中,要经常创建一个PHP变量,底层就是一个zval指针。早期的版本都是通过MAKE_STD_ZVAL动态的从堆上分配一个zval内存。而PHP7可以直接使用栈内存了。
PHP5:
zval *val;MAKE_STD_ZVAL(val);

PHP7
zval val;

左边是PHP5的zval(24字节),右边是PHP7的zval(16字节);

可以看出来php7的zval要比php5还要复杂,但是却能从24个字节下降到16个字节,为什呢?

在C语言中struct的每一个成员变量要各自占据一块独立的内存空间,而union里的成员变量是共用一块内存空间(php7中大量使用union替换了struct)。因此,虽然成员变量看起来多了不少,但是实际占据的内存空间有很多都是公用的却下降了。


  • Zend Array替换HashTale结构
我们php程序中使用最多、最有用、最方便、最灵活的就是数组了,而php5它的底层就是HashTable实现的,php7使用了新的Zend Array类型,性能和访问速度上都有了大幅度提升!zend_string存储hash值,array查询不再需要重复计算hash值。PHP7为字符串单独创建了新类型叫做zend_string,除了char*指针和长度之外,增加了一个hash字段,用于保存字符串的hash值。下图是zend_string的结构体, 里面 的h就是用来存储hash值:


如类的属性、类的方法都要hash查找,找到zval的指针,再执行相应的操作。早期版本zned引擎有大量时间用于CPU计算hash值。
  • hashtable桶内直接存数据,减少了内存的申请次数,提升cache命中率和内存访问速度


早期的arBuckets的每一个桶存一次数据,就要申请一次内存,存n次得申请n次,而现在只要arData申请一个大内存,就可以有n个桶,存n次数据,这样速度就会提升了很多。如访问2号桶和4号桶时,因为他们在同一个内存页上,所以访问他们的时候,命中率就会高很多,速度急速提升。
  • Zend_parse_parameters改为宏实现,性能提升5%
在php之前的版本中,这部分主要是C的函数直接来处理,她主要来解析一下字符串的参数,转换为你所需要的一些的变量,而php7则改为将这个函数转换为宏来实现,直接获取到每一项元素的值,不需要再去执行这个函数。这样的优化,就是让php性能提升了5%。
  • 新增4种OPCODE
什么是opcode呢?简答的说opcode 是指在手机上通过输入一定的指令,对手机进行功能上的调整,是php程序执行的最基本单位。 PHP是构建在Zend虚拟机(Zend VM)之上的,PHP的opcode就是Zend虚拟机中的指令。call_user_function、is_int/is_string/is_array、strlen、defined 4种函数平时是比较常用的,php7就把他们变为直接可以执行的opcode指令,速度更快。call_user_function(_array) => ZEND_INIT_USER_CALL、is_int/string/array/* => ZEND_TYPE_CHECK、
strlen => ZEND_STRLEN、defined => ZEND+DEFINED
  • 基础类型直接改为值拷贝
int、floor、bool直接改为值拷贝。

  • 排序算法改进
php5是直接使用C函数的排序算法,而官方开发组在php7重新写了Zend_sort排序算法,来对排序算法进行性能优化。PHP5 快速排序(非稳定排序)   PHP7 快速排序+选择排序(稳定排序)

  • PCRE with JIT
正则表达式可以编译为机器码。

  • 使用gdb4.8的PGO功能
线上php运行一段时间,会导出一份运行时的数据统计,最后我们在重新编译一次php,把上次统计结果给gdb,会生成更适合程序运行的php版本,gdb对php性能就行了优化。

  • PHP7 JIT
所谓的JIT就是just in time的缩写,运行时将指令转化为二进制机器码。针对于计算密集型的程序,JIT可以将PHP的OPCODE转化为可以直接运行的二进制机器码,大幅提升性能。为什么7.0版本没有增加JIT?因为对于实际项目并没有提升性能,如wordpress。php开发组已重启JIT开发计划,后续版本会增加JIT的。
  • 64位的INT支持
  • 支持存储大于2GB的字符串
  • 支持上传大小大于2GB的文件
  • 保证字符串在所有平台上【64位】都是64bit
  • 新增几个运算符 
<=>   比较两个数的大小【-1:前者小于后者,0:前者等于后者,1:前者大于后者】
**  【a的b次方】
?? NULL 合并运算符   // 如果 $_GET['user'] 不存在返回 'nobody',否则返回 $_GET['user'] 的值$username = $_GET['user'] ?? 'nobody';// 类似的三元运算符$username = isset($_GET['user']) ? $_GET['user'] : 'nobody';
\u{xxxx} - Unicode字符的解析
整除运算符  intdiv()  intdiv(10,3) => int(3)
  • 返回类型的声明

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值