【php】php7新特性及其优化原理
PHP7新特性
php7.x增加的新特性介绍可以参考这里:
https://www.runoob.com/php/php7-new-features.html
https://php.net/manual/zh/migration70.new-features.php
php7.x版本系列相比之前的php的版本提交性能提高了不少,下图是wordpress在不同php版本下的压力测试表现。


这里面其中的一些主要改变是性能提高的关键,主要有以下内容。
1.zval使用栈内存
在zend引擎和扩展中,经常要创建php变量,其底层就是一个zval指针,之前的php版本都是通过MAKE_STD_ZVAL动态的从堆内存上分配一个zval内存。而php7直接使用栈内存,好处是少了一次内存分配。php程序中回大量创建变量,所以php7会在栈上预分配一块内存来存放这些zval,来节省大量的内存分配和管理操作。
php5
zval *val ; MAKE_STD_ZVAL(val)
php7
zval val;
2.zend_string存储hash值,array查询不再需要重复计算hash
数组是php比较重要的数据结构,php程序中会有大量的array关联查询,虽然hashtable查找的复杂度是O(1),但是key的值每次要转化成一个hash值,需要用一个复杂的hash函数去计算的,这样就会占用cpu时间,不过不光数组,在php底层很多地方都会用到hashtable,比如类的属性方法函数等。其实php程序运行起来大部分key的值是不变的,所以php7就保存了这些hash值下次直接使用,那么php7就为字符串单独创建了新类型叫做zend_string,除了char*指针和长度之外,增加了一个hash字段,用于保存字符串的hash值,数据键值查找不再反复需要计算hash值。为了优化数组的键值查找。

上图代码中 zend_ulong h;就是存储hash值。
3.hashtable桶内直接存放数据,减少了内存申请次数,顺便也提升了cache命中率和访问速度。因为指针不是连续的是分布在不同的内存页上,如果读取第一个或者第三个桶,它们的数据可能会在两个页上。
php7之前

数据存放是在上图arBuckets这个结构体上,存放了一些bucket * 指针,指针上就是对应了一些数据。php7对这些做了一些改进,如下图。
php7

php7将之前arBuckets改成了上图中的arData,而这个arData直接就是一个大块内存,这个内存上面就是一个个桶bucket,这样的好处就是每次数据就不需要动态去申请内存。
4.zend_parse_parameters改为宏实现,性能提升15%。
5.新增加4种opcode,call_user_function(),is_int(),is_string(),is_array(),strlen(),defined() 4个函数变为php opcode指令,速度更快。
6.PHP7 的内核中有一个重要的变化是加入了 AST(Abstract syntax tree)抽象语法树,指代码在计算机内存的一种树状数据结构,树上的每个节点都表示源代码中的一种结构,便于计算机理解和解析。

在 PHP5系列版本中,从 php 脚本到 opcodes 的执行的过程如下:
词法扫描分析(Lexing):将源文件转换成 token 流;
语法分析(Parsing):生成 op arrays。
PHP7 中在语法分析阶段先生成 AST:
词法扫描分析(Lexing):将源文件转换成 token 流。
语法分析(Parsing):从 token 流生成抽象语法树。
Compilation:从抽象语法树生成 op arrays。
这个表达式($a)['b'] = 1 就会被解析成下图这样的一棵树结构

7.其他更多性能优化,如基础类型 float , int , bool等改成直接进行值拷贝。排序算法改进了,PCER with JIT , execute_data和opline使用全局寄存器,使用gdb4.8的PGO功能。
8.php7与JIT
最初HHVM退出一个很重要的特性就是JIT,JIT就是just in time的缩写,表示运行时候将指令转换成二进制机器码,我们知道C和C++是将源代码编译然后生成二进制机器码去执行的,而php,python等脚本语言是将源代码转换成中间指令然后在vm(虚拟机)上执行,另外java系语言他们使用的JVM引擎底层也是JIT,是将java的字节码编译成二进制的机器码去执行的。对于计算密集型的的程序,JIT可以将PHP的opcode直接转换成机器码,可以大幅度提升PHP性能。
不过PHP7.0-final版本中不会带有JIT特性的。
但是
为什么php7版本没有使用JIT呢?
是因为php官方之前有个php中间版本是带有JIT的,后来php官方开发组使用JIT测试时候发现JIT对于实际项目的性能没有太大的性能提升,所以最终放弃使用JIT方案。但后来发现密集计算性的php程序使用JIT后性能还会大幅提升。
PHP7下载与安装
1.第一步 下载源代码
wget https://www.php.net/distributions/php-7.2.21.tar.bz2
2.第二步 解压源代码
tar -xjvf php-7.2.21.tar.bz2
3.第三步 进入目录
cd php-7.2.21
4.第四步 执行configure shell脚本检测环境及配置php安装目录 比如检测php安装是否必须要有gcc 和 authconfig等工具
./configure --prefix=/usr/local/src/php7
出现下面提示说明上面执行成功
Generating files
configure: creating ./config.status
creating main/internal_functions.c
creating main/internal_functions_cli.c
+--------------------------------------------------------------------+
| License: |
| This software is subject to the PHP License, available in this |
| distribution in the file LICENSE. By continuing this installation |
| process, you are bound by the terms of this license agreement. |
| If you do not agree with the terms of this license, you must abort |
| the installation process at this point. |
+--------------------------------------------------------------------+ Thank you for using PHP. 5.第五步 编译安装 make && make install 出现下面提示说明make成功
clicommand.inc
directorygraphiterator.inc
invertedregexiterator.inc
pharcommand.inc
phar.inc Build complete.
Don't forget to run 'make test'.
出现下面提示说明make install成功
Installing PEAR environment: /usr/local/src/php7/lib/php/
[PEAR] Archive_Tar - installed: 1.4.7
[PEAR] Console_Getopt - installed: 1.4.2
[PEAR] Structures_Graph- installed: 1.1.1
[PEAR] XML_Util - installed: 1.4.3
[PEAR] PEAR - installed: 1.10.9
Wrote PEAR system config file at: /usr/local/src/php7/etc/pear.conf
You may want to add: /usr/local/src/php7/lib/php to your php.ini include_path
/usr/local/src/php-7.2.21/build/shtool install -c ext/phar/phar.phar /usr/local/src/php7/bin
ln -s -f phar.phar /usr/local/src/php7/bin/phar
Installing PDO headers: /usr/local/src/php7/include/php/ext/pdo/
验证php安装成功
songguojundeMBP:php7 songguojun$ pwd
/usr/local/src/php7
songguojundeMBP:php7 songguojun$ ls
bin etc include lib php var
songguojundeMBP:php7 songguojun$ cd bin/
songguojundeMBP:bin songguojun$ ./php -v #显示php版本 下面打印出php版本说明php安装成功
PHP 7.2. (cli) (built: Feb ::) ( NTS )
Copyright (c) - The PHP Group
Zend Engine v3.1.0, Copyright (c) - Zend Technologies
如果php命令找不到就添加到启动文件中
songguojundeMBP:~ songguojun$ vim ~/.bash_profile
alias ll='ls -alF'
alias la='ls -A'
export PATH="/usr/local/opt/libiconv/bin:$PATH"
alias php=/usr/local/src/php7/bin/php songguojundeMBP:~ songguojun$ source ~/.bash_profil
源码安装可能会出现的问题:
1. 缺少libiconv提示
checking for iconv support... yes
checking for iconv... no
checking for libiconv... no
configure: error: Please specify the install prefix of iconv with --with-iconv=<DIR>
下载libiconv库
brew install libiconv
【php】php7新特性及其优化原理的更多相关文章
- PHPStorm使用PHP7新特性出现红色波浪错误
今天在项目中使用PHP7新特性时PHPStorm出现了如下红色错误,看着让人很不舒服,明明没有错 本地配置LNMP的PHP版本是7.2所以不是安装的PHP版本过低的问题,而是PHPStorm默认支持的 ...
- PHP7 新特性 简介
整理了一些常用的新特性,欢迎点赞!!! 新增操作符 1.?? $username = $_GET['user'] ?? ''; $username = isset($_GET['user']) ? $ ...
- PHP7新特性
重写ZenVM,性能比PHP5.6提升300% 新特性: 1.变量类型(为PHP7.1的JIT特性做准备)function test(int $a, string $b, array $c) : in ...
- PHP7新特性 What will be in PHP 7/PHPNG
本文结合php官网和鸟哥相关文章总结: 官网:http://www.php7.ca/ https://wiki.php.net/phpng PHP7将在2015年10月正式发布,PHP7 ,将会是 ...
- PHP7新特性的介绍
关于PHP 20年的发展历史: 迄今为止最流行的WEB开发语言: 超过82%的网站都会使用PHP作为他们的服务端开发语言: 新特性介绍 PHP NG – Zend Engine 3 抽象语法树 64位 ...
- php7 新特性整理
PHP7 已经出来1年了,PHP7.1也即将和大家见面,这么多好的特性,好的方法,为什么不使用呢,也希望PHP越来越好. 在这里整理 PHP 5.1 ,PHP5.2,PHP5.3,PHP5.4,PHP ...
- php7+新特性
php7已经发布有段时间了,查了下正式版本的发布时间是2015年底,至于具体的新特性,在这里总结一下. 标量类型声明 php7新增了4种类型, 字符串(string), 整数 (int), 浮点数 ( ...
- php7新特性总结
PHP新功能总结 改进的性能 - 将PHPNG代码合并到PHP7中,速度是PHP 5的两倍. 降低内存消耗 - 优化的PHP 7使用较少的资源. 标量类型声明 - 现在可以强制执行参数和返回类型. 一 ...
- php7新特性的理解和比较
1. null合并运算符(??) ??语法: 如果变量存在且值不为NULL,它就会返回自身的值,否则返回它的第二个操作数. //php7以前 if判断 if(empty($_GET['param']) ...
随机推荐
- 【spring实战第五版遇到的坑】3.2中配置关系映射时,表名和3.1中不一样
3.2章中按照书中的步骤写好相应类的映射关系,发现启动时,之前在3.1章中建的表全部被删重新建立了,并且Ingredient表的数据没了,由于使用了JPA,默认使用的是hibernate,在启动时会删 ...
- 002. https通信(CA证书认证 + 密钥商定 )
服务端与客户端建立https通信的过程: 一.认证:客户端第一次访问服务端时,要求服务端证明自己可被信任 1.证书:由服务端申请.第三方CA颁发的,存放在服务端的证书: 证书包含:服务端的公钥.服务端 ...
- axios 封装
来自:https://www.jianshu.com/p/68d81da4e1ad 侵删 import axios from 'axios' import qs from 'qs' let baseu ...
- VSCode中快捷输入HTML代码
VSCode中有一些快捷编辑HTML的方法,能大大提高工作效率,在这记录一些. 1.输入html:5,然后按tab键或enter键,效果如下: <!-- 输入html或者html:5生成页面模板 ...
- ext组件中的查询
组件中的查询依赖于组件树,往上可追溯父组件,往下可查找子组件. 组件中的查询主要包括8个方法:up.down.query.child.nextNode.nextSibiling.previoutNod ...
- Oracle 安装步骤、安装中错误处理、完整卸载
/*************************************************以下ORACLE服务端安装************************************* ...
- centos7的内核区别
最近重新搭建环境准备测试一些东西,在网上随意下载了一个镜像,名字叫做:CentOS-7-i386-Everything-1810 下载完之后开始做实验安装软件的时候发现一直报错:[Errno 14] ...
- html页面打开ie浏览器默认打开最高版本
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
- 19 款仿 Bootstrap 后台管理主题免费下载
声明: 1. 本篇文章提到的仿 Bootstrap 风格的主题,是基于 jQuery 的 ASP.NET MVC 控件库的主题. 2. FineUIMvc(基础版)完全免费,可以用于商业项目. 目录 ...
- destruct析构函数里操作文件出现的问题
这几天要给后台加一个记录操作日志的功能,可是项目已经开发完了不可能再去改以前的代码了,那有什么快捷的方法呢? 项目使用的ThinkPHP3.23 ,为了方便权限控制,后台控制器结构为:普通控制器 ex ...