php7和PHP5对比的新特性和性能优化
1 抽象语法树( AST)
1)在 PHP5中,从 php 脚本到 opcodes 的执行的过程是:
Lexing:词法扫描分析,将源文件转换成 token 流;
Parsing:语法分析,在此阶段生成 op arrays。
2)PHP7 中在语法分析阶段不再直接生成 op arrays,而是先生成 AST,所以过程多了一步:
Lexing:词法扫描分析,将源文件转换成 token 流;
Parsing:语法分析,从 token 流生成抽象语法树;
Compilation:从抽象语法树生成 op arrays。
添加了抽象语法树:内存的使用增加了,但是执行时间上却有所降低
AST在PHP编译过程作为一个中间件的角色,替换原来直接从解释器吐出opcode的方式,让解释器(parser)和编译器(compliler)解耦,可以减少一些Hack代码,同时,让实现更容易理解和可维护
2 Natice TLS
PHP在多线程模式下,需要解决“线程安全”(TS,Thread Safe)的问题,因为线程是共享进程的内存空间的,所以每个线程本身需要通过某种方式,构建私有的空间来保存自己的私有数据,避免和其他线程相互污染。
而PHP5采用的方式,就是维护一个全局大数组,为每一个线程分配一份独立的存储空间,线程通过各自拥有的key值来访问这个全局数据组。而这个独有的key值在PHP5中需要传递给每一个需要用到全局变量的函数,PHP7认为这种传递的方式并不友好,并且存在一些问题。因而,尝试采用一个全局的线程特定变量来保存这个key值。
3 指定参数 返回值类型
PHP语言一个非常重要的特点就是“弱类型”,它让PHP的程序变得非常容易编写.
PHP7可选的方式支持类型定义,除此之外,还引入了一个开关指令declare(strict_type=1);,当这个指令一旦开启,将会强制当前文件下的程序遵循严格的函数传参类型和返回类型。
4 zval 结构的变化
在PHP5的时候, zval的定义如下:
struct _zval_struct {
union {
long lval;
double dval;
struct {
char *val;
int len;
} str;
HashTable *ht;
zend_object_value obj;
zend_ast *ast;
} value;
zend_uint refcount__gc;
zend_uchar type;
zend_uchar is_ref__gc;
};
首先这个结构体的大小是(在64位系统)24个字节, 我们仔细看这个zval.value联合体, 其中zend_object_value是最大的长板, 它导致整个value需要16个字节, 这个应该是很容易可以优化掉的, 比如把它挪出来, 用个指针代替,因为毕竟IS_OBJECT也不是最最常用的类型.
第二, 这个结构体的每一个字段都有明确的含义定义, 没有预留任何的自定义字段, 导致在PHP5时代做很多的优化的时候, 需要存储一些和zval相关的信息的时候, 不得不采用其他结构体映射, 或者外部包装后打补丁的方式来扩充zval, 比如5.3的时候新引入专门解决循环引用的GC, 它不得采用如下的比较hack的做法
第三, PHP的zval大部分都是按值传递, 写时拷贝的值, 但是有俩个例外, 就是对象和资源, 他们永远都是按引用传递, 这样就造成一个问题, 对象和资源在除了zval中的引用计数以外, 还需要一个全局的引用计数, 这样才能保证内存可以回收. 所以在PHP5的时代, 以对象为例, 它有俩套引用计数, 一个是zval中的, 另外一个是obj自身的计数:
第四, 我们知道PHP中, 大量的计算都是面向字符串的, 然而因为引用计数是作用在zval的, 那么就会导致如果要拷贝一个字符串类型的zval, 我们别无他法只能复制这个字符串. 当我们把一个zval的字符串作为key添加到一个数组里的时候, 我们别无他法只能复制这个字符串. 虽然在PHP5.4的时候, 我们引入了INTERNED STRING, 但是还是不能根本解决这个问题.
还比如, PHP中大量的结构体都是基于Hashtable实现的, 增删改查Hashtable的操作占据了大量的CPU时间, 而字符串要查找首先要求它的Hash值, 理论上我们完全可以把一个字符串的Hash值计算好以后, 就存下来, 避免再次计算等等
第五, 这个是关于引用的, PHP5的时代, 我们采用写时分离, 但是结合到引用这里就有了一个经典的性能问题:
第六, 也是最重要的一个, 为什么说它重要呢? 因为这点促成了很大的性能提升, 我们习惯了在PHP5的时代调用MAKE_STD_ZVAL在堆内存上分配一个zval, 然后对他进行操作, 最后呢通过RETURN_ZVAL把这个zval的值”copy”给return_value, 然后又销毁了这个zval, 比如pathinfo这个函数:
5 异常处理
PHP 5 的 try ... catch ... finally 无法处理传统错误,如果需要,你通常会考虑用 set_error_handler() 来 Hack 一下。但是仍有很多错误类型是 set_error_handler() 捕捉不到的
PHP 7引入 Throwable 接口,错误及异常都实现了 Throwable,无法直接实现 Throwable,但可以扩展 \Exception 和 \Error 类。可以用 Throwable 捕捉异常跟错误。\Exception 是所有PHP及用户异常的基类;\Error 是所有内部PHP错误的基类。
$name = "Tony";
try {
$name = $name->method();
} catch (\Error $e) {
echo "出错消息 --- ", $e->getMessage(), PHP_EOL;
}
try {
$name = $name->method();
} catch (\Throwable $e) {
echo "出错消息 --- ", $e->getMessage(), PHP_EOL;
}
try {
intdiv(5, 0);
} catch (\DivisionByZeroError $e) {
echo "出错消息 --- ", $e->getMessage(), PHP_EOL;
}
6 hashtable 的变化
7 执行器
8 新的参数解析方式
PHP5 对应的参数解析 zend_parse_parament,
PHP7对应的参数解析:fast_zpp
————————————————
版权声明:本文为CSDN博主「fish_study_csdn」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/fish_study_csdn/article/details/80407755
php7和PHP5对比的新特性和性能优化的更多相关文章
- php8.0正式版新特性和性能优化学习
前言 PHP团队宣布PHP8正式GA(链接).php的发展又开启了新的篇章,PHP8.0.0版本引入了一些重大变更及许多新特性和性能优化机制.火速学习下~ JIT(Just in Time Compi ...
- Node.js V0.12 新特性之性能优化
v0.12悠长的开发周期(已经过去九个月了,并且还在继续,是有史以来最长的一次)让核心团队和贡献者们有充分的机会对性能做一些优化. 本文会介绍其中最值得注意的几个. http://www.infoq. ...
- Node.js V0.12新特性之性能优化
v0.12悠长的开发周期(已经过去九个月了,并且还在继续,是有史以来最长的一次)让核心团队和贡献者们有充分的机会对性能做一些优化.本文会介绍其中最值得注意的几个. 支持塞住模式的可写流 现在可写流可以 ...
- PHP5.4.0新特性研究
PHP5.4.0新特性研究 1.内建Web Server 这的确是个好的改进,大大的方便了开发人员.以后开发机不装nginx,httpd也行 cd $PHP_INSTALL_PATH ./bin/ph ...
- Git 2.7: 一个新的带来许多新特性和性能提升的主要版本
在2.6版本发布两个月之后,Git 2.7发布.该版本带来了许多新特性以及性能的提升. 本文选取了Git 2.7带来的主要变化: git remote支持get-url子命令,可以显示指定远端的URL ...
- php5.5之后新特性整理
1 生成器 yield关键字yield的中文文档在这里:http://php.net/manual/zh/language.generators.overview.php查看文档,能知道yield的一 ...
- PHP5.3、PHP5.4、PHP5.5、PHP5.6的新特性
1. PHP5.3中的新特性 1.1 支持命名空间(namespace) 毫无疑问,命名空间是PHP5.3所带来的最重要的新特性. 在PHP5.3中,可以用命名空间防止代码的冲突,命名空间的分隔符为 ...
- PHP5.5的新特性
看了@轩脉刃 今天出炉的PHP 5.5 新特性.不过没有翻译全,我这里稍微补充下,整理成完整的一篇:) 原文:http://www.php.net/manual/zh/migration55.new- ...
- 一些新的web性能优化技术
1.IconFont:图标字体,这是近年来新流行的一种以字体代替图片的技术.它可以适应任何分辨率而不会出现图片模糊问题,与图片相比它具有更小的容量,更高的灵活性(像字体一样可以设置图标大小.颜色.透明 ...
随机推荐
- Vs中包含目录、库目录、附加包含目录、附加库目录、附加依赖项之详解
VS项目中的包含目录.库目录.附加包含目录.附加库目录.附加依赖项均在"项目->属性->配置属性"下进行配置,具体说明如下: VC++目录: 包含目录:寻找#inclu ...
- MySQL查询top N记录
下面以查询每门课程分数最高的学生以及成绩为例,演示如何查询 top N记录.下图是测试数据,表结构和相关 insert 脚本见<常用SQL之日期格式化和查询重复数据>. 使用自连接[推荐] ...
- JavaWeb_(Mybatis框架)主配置文件介绍_四
系列博文: JavaWeb_(Mybatis框架)JDBC操作数据库和Mybatis框架操作数据库区别_一 传送门 JavaWeb_(Mybatis框架)使用Mybatis对表进行增.删.改.查操作_ ...
- zabbix监控windows案例
首先在zabbix官网下载zabbix软件包:https://www.zabbix.com/ 下载完成之后,将其解压到D盘 # 配置与安装,配置zabbix agent相关配置. 找到conf下的配置 ...
- RuntimeException和Exception的区别
1.java将所有的错误封装为一个对象,其根本父类为Throwable, Throwable有两个子类:Error和Exception. 2.Error是Throwable 的子类,用于指示合理的应用 ...
- Java并发指南12:深度解读 java 线程池设计思想及源码实现
深度解读 java 线程池设计思想及源码实现 转自 https://javadoop.com/2017/09/05/java-thread-pool/hmsr=toutiao.io&utm_ ...
- 使用PyMySQL连接MySQL错误
使用PyMySQL连接MySQL错误 之前写了一个小项目,今天突然想起来,准备优化一下,但是原本好好的项目竟然跑不起来了 emmm....我真的啥都没干呀 具体错误是这样的: Traceback (m ...
- LightGBM两种使用方式
原生形式使用lightgbm(import lightgbm as lgb) import lightgbm as lgb from sklearn.metrics import mean_squar ...
- Zynq_soc学习
Zynq_soc学习 SFP高速串行通信得搞来看看 最小系统 PL端时钟配置: 配置DDR控制器,主要是添加DDR正确的型号 外设电平接口配置: BANK0:LVCMOS3.3 BANK1:LVCMO ...
- vue常用的修饰符
v-model修饰符 <template> <div id="demo14"> <p>-----------------模板语法之修饰符---- ...