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下降了,因此总的耗时下降了很多)this

 

 

三 hashtable桶内直接存数据

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

四 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指令,执行更快。code

六 其余更多优化

除了上面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的开发工做。

相关文章
相关标签/搜索