PHP7做了哪些优化

一  zval使用栈内存

在Zend引擎和扩展中,经常要创建一个PHP的变量,底层就是一个zval指针。之前的版本都是通过MAKE_STD_ZVAL动态的从堆上分配一个zval内存。而PHP7可以直接使用栈内存。PHP代码中创建的变量也进行了优化,PHP7直接在栈内存上预分配zval。这样节约了大量内存分配和内存管理的操作。

PHP5

zval *val; MAKE_STD_ZVAL(val);

PHP7

zval val;

二 zend_string存储hash值,array查询不再需要重复计算hash

PHP7为字符串单独创建了新类型叫做zend_string,除了char *指针和长度之外,增加了一个hash字段,用于保存字符串的hash值。PHP中array是核心数据结构,PHP程序中往往都有大量的$array[$key]操作,虽然hashtable查找的时间复杂度是O(1),但$key要转为hash值是要经过计算的。不仅仅是array操作,实际上PHP底层对于类属性、类方法、函数,访问时都要先通过hashtable查找到对应的指针,再执行对应的操作。PHP7之前Zend引擎会有大量的CPU时间用于计算hash值。

实际上PHP程序运行起来之后,大部分情况下$key的值都是不变的。PHP7干脆将这个hash值保存起来,下次直接使用,这样就节省了大量的hash计算操作,PHP的hashtable与C数

组的性能一致。

从实际项目进行callgrind性能分析,会发现alloc和hash 2项操作就占用了相当大比例的CPU时间。PHP7优化之后这2项操作占用的CPU时间降低了非常多。(注:zend_hash仍然占12%,因为整体CPU降低了,所以总的耗时降低了不少)

三 hashtable桶内直接存数据

PHP5的hashtable每个元素都是一个 Bucket *,而PHP7直接存Bucket,减少了内存申请次数,提升了Cache命中率和内存访问速度。

四 zend_parse_parameters改为宏实现

PHP的C扩展函数与PHP中的变量进行参数输入时,要使用zend_parse_parameters()函数,这个函数根据一个字符串参数找到对应PHP的zval指针,然后进行赋值。 这个函数实际上有一定的性能消耗。PHP7直接使用宏替换了zend_parse_parameters函数,C扩展中不再需要使用zend_parse_parameters进行逐个参数的查找,宏展开后自动会实现参数赋值。仅此一项就提升了5%的性能。

五 新增加4种OPCODE

很多PHP程序中会大量使用call_user_function, is_int/string/array,  strlen , defined 函数。PHP5 都是以扩展函数的方式提供,PHP7中这4类函数改成ZendVM的OPCODE指令,执行更快。

六 其他更多优化

除了上面5个主要优化点之外,PHP7还有其他更多的细节性能优化。如基础类型int、float、bool等改为直接进行值拷贝,排序算法改进,PCRE with JIT,execute_data和opline使用全局寄存器等等。PHP7对性能的优化会继续进行下去。

PHP7-alpha相比PHP5.6性能提升了近3倍。下面是WordPress在PHP7上的表现:

PHP7的新特性

除了性能优化外,PHP7新增加了2项重要的新特性。

1. 变量类型

PHP7版本函数的参数和返回值增加了类型限定。为什么PHP要加入类型,实际上此项特性是为了PHP7.1版本的JIT特性做准备,增加类型后PHP JIT可以准确判断变量类型,生成最佳的机器指令。

function test(int $a, string $b, array $c) : int {
  //code
}

2. 错误异常

PHP程序出错后过去Zend引擎会发生致命错误并终止程序运行,PHP7可以使用try/catch捕获错误。底层使用Exeception代替了Fatal Error。这个特性表示PHP语言正在向一个更加规范的方向发展。应用层与底层在错误抛出的方式全部统一为异常。

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

3. 匿名类

$test = new class("Hello World") {
  public function __construct($greeting) {
      $this->greeting = $greeting;
  }
};

PHP7与JIT

最初PHP7性能优化的方向并不是以上所讲的,而是JIT。JIT是just in time的缩写,表示运行时将指令转为二进制机器码。Java语言的JVM引擎底层就是使用JIT将Java字节码编译为二进制机器码执行。PHP7开发过程中有一个中间版本是基于JIT,后来开发组发现使用JIT后,对于实际项目并没有有太大的性能提升,所以PHP7最终放弃了JIT方案,PHP7.0-final版本不会携带JIT特性。

但如果是密集计算类程序就不同了,使用JIT将PHP OpCode编译为机器码,运算的性能会大幅提升。PHP官方开发组在2014年底重启了JIT的开发工作。

原文地址:https://www.cnblogs.com/kynewu/p/8971299.html

时间: 2024-11-12 20:53:57

PHP7做了哪些优化的相关文章

【webapp的优化整理】要做移动前端优化的朋友进来看看吧

单页or多页 本文仅代表个人观点,不足请见谅,欢迎赐教. webapp 小钗从事单页相关的开发一年有余,期间无比的推崇webapp的网站模式,也整理了很多移动开发的知识点,但是现在回过头来看,webapp究竟是好还是不好真是一言难尽哟! webapp使用JavaScript修改页面:紧接着再从服务器传递更多数据然后再修改页面,如此循环. 从性能的角度看,在现代浏览器中单页面Web App已经能够和普通native应用程序相媲美,而且几乎所有的操作系统都支持现代的浏览器. 所以,很多人认为weba

【转载】PHP7革新与性能优化

PHP7革新与性能优化 http://hansionxu.blog.163.com/blog/static/24169810920158704014772/ PHP7和HHVM的性能之争 http://www.csdn.net/article/2014-12-25/2823234

根据网站所做的SEO优化整理的一份文档

今日给合作公司讲解本公司网站SEO优化整理的一份简单文档 架构 ########################################## 1.尽量避免Javascript和flash导航. 虽然JS和FLASH能把网站做的绚丽漂亮,但目前搜索引擎还是无法顺利的抓取其中的内容,所以我们要避免. 2.目录层次不能太深. 网站目录尽量保持在三层以内,尽可能接近根网址,比如“www.xxx.com/产品目录/产品名称”明显比“www.xxx.com/产品目录/年份/月份/产品名称”要好. 3

面试:做过sql优化吗?

近来面试找工作经常会遇见这种问题: 做过数据库优化吗?大数据量基础过吗?系统反应慢怎么查询? 这咱也没背过啊,面试还老问,现在的网站主要的压力都来自于数据库,频繁的数据库访问经常会使系统瘫痪,这样就需要进行sql优化.明天去58面试,今天来梳理一下. 1. 写明查询具体某几列,减少*的使用,表名过长时,尽量使用表的别名 *和列名一样 2,在业务密集的SQL当中尽量不采用IN操作符,用EXISTS 方案代替. in 和 exists的区别: 如果子查询得出的结果集记录较少,主查询中的表较大且又有索

PHP7革新与性能优化

有幸参与2015年的PHP技术峰会(PHPCON),听了鸟哥(惠新宸)的关于PHP7的新特性和性能优化的分享,一切都令人感到激动.鸟哥是国内最权威的PHP专家,他的分享有很多非常有价值的东西,我通过整理分享的PPT和收集相关资料,整理为这篇解读性质的技术文章,希望能给做PHP开发的同学一些帮助. PHP已经走过了20年的历史,直到今天,PHP7都发布了RC版,据说,PHP7正式版应该会在2015年11月份左右发布.PHP7对于上一个系列的PHP5.*,可以说是一个大规模的革新,尤其是在性能方面实

自动安装php7(配置未优化版本)

#!/bin/bash #by dxd in 2017-6 #only suit for centos/aliyun os, and based on aliyun install script CURR_PATH=$(pwd) DOWNLOAD_LIBMCRYPT_URL=http://download.verymall.cn/libmcrypt-2.5.8.tar.gz DOWNLOAD_PHP7_URL=http://download.verymall.cn/php7.bz2 DOWNLO

HDU - 1248 寒冰王座(完全背包做法和暴力优化做法)

题意:完全背包裸题 每件物品的cost就是它的value. 1.完全背包法 1 #include <iostream> 2 using namespace std; 3 4 const int maxn=11111; 5 int dp[maxn]; 6 7 int main(){ 8 int t; 9 cin>>t; 10 int value[4]={0,150,200,350}; 11 while(t--){ 12 int n; 13 cin>>n; 14 for(i

安装完ubuntu16.4.0之后要做的一些优化

1.删除libreoffice libreoffice虽然是开源的,但是Java写出来的office执行效率实在不敢恭维,装完系统后果断删掉 [html] view plain copy sudo apt-get remove libreoffice-common 2.删除Amazon的链接 [html] view plain copy sudo apt-get remove unity-webapps-common 3.删掉基本不用的自带软件(用的时候再装也来得及) [html] view p

django 开发中数据库做过什么优化??

1.设计表时,尽量少使用外键,因为外键约束会影响插入和删除性能: 2.使用缓存,减少对数据库的访问: 3.在 orm 框架下设置表时,能用 varchar 确定字段长度时,就别用 text: 4.可以给搜索频率高的字段属性,在定义时创建索引: 6.如果一个页面需要多次连接数据库,最好一次性取出所有需要的数据,减少对数据库的查询次数: 7.若页面只需要数据库里某一个两个字段时,可以用 QuerySet.values(): 8.在模板标签里使用 with 标签可以缓存 Queryset的查询结果.