Recommended (free): PHP7
1. Abstract syntax tree (AST)
1) In PHP5, the execution process from php script to opcodes is:
2) In PHP7, op arrays are no longer directly generated during the syntax analysis phase, but AST is generated first. , so there is one more step in the process:
Added abstract syntax tree: memory usage increased, but execution time decreased
AST plays the role of a middleware in the PHP compilation process, replacing the original method of spitting out opcode directly from the interpreter, decoupling the interpreter (parser) and the compiler (compliler). It can reduce some Hack code, and at the same time, make the implementation easier to understand and maintain
2. Natice TLS
##PHP needs to solve the problem of "Thread Safety" (TS, Thread Safe) in multi-threaded mode. Because threads share the memory space of the process, each thread itself needs to be constructed in some way. Private space to save your own private data to avoid mutual contamination with other threads.
The method adopted by PHP5 is to maintain a global large array and allocate an independent storage space to each thread. The threads access this global data group through their own key values. . This unique key value needs to be passed to every function that needs to use global variables in PHP5. PHP7 believes that this method of passing is not friendly and has some problems. Therefore, try to use a global thread-specific variable to save this key value.
3. Specify the parameter return value type
A very important feature of the PHP language is "weak typing". It makes PHP programs very easy to write.
PHP7 optionally supports type definition. In addition, it also introduces a switch instruction declare(strict_type=1); , once this instruction is turned on, it will force the program under the current file to follow strict function parameter types and return types.
4. Changes in zval structure
In PHP5, zval is defined as follows: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; };
First of all, the size of this structure is 24 bytes (on a 64-bit system). Let's take a closer look at this zval.value union. zend_object_value is the largest long board, which causes the entire value to require 16 words. section, this should be easy to optimize, such as moving it out and replacing it with a pointer, because after all, IS_OBJECT is not the most commonly used type.
Second, each field of this structure has a clear meaning, and no custom fields are reserved. As a result, when doing a lot of optimizations in the PHP5 era, some information related to zval needs to be stored. You have to use other structure mapping, or external packaging and patching to expand zval. For example, in 5.3, a new GC was introduced to specifically solve circular references. It must not adopt the following relatively hacky approach
Third, most of PHP's zvals are passed by value, and the value is copied when writing. However, there are two exceptions, which are objects and resources. They are always passed by reference, so This creates a problem. In addition to the reference count in zval, objects and resources also need a global reference count to ensure that the memory can be recycled. So in the era of PHP5, taking objects as an example, it has two sets of reference counts. One is in zval, and the other is the count of obj itself:
第四, 我们知道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 { intp(5, 0); } catch (\pisionByZeroError $e) { echo "出错消息 --- ", $e->getMessage(), PHP_EOL; }
6、hashtable 的变化
7、执行器
8、新的参数解析方式
PHP5 对应的参数解析 zend_parse_parament,
PHP7对应的参数解析:fast_zpp
The above is the detailed content of Let's take a look at the new features and performance optimizations of php7 and PHP5.. For more information, please follow other related articles on the PHP Chinese website!