日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > php >内容正文

php

php7和PHP5对比的新特性和性能优化

發(fā)布時(shí)間:2023/12/14 php 50 豆豆
生活随笔 收集整理的這篇文章主要介紹了 php7和PHP5对比的新特性和性能优化 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

1? 抽象語法樹(?AST)

? ?1)在 PHP5中,從 php 腳本到 opcodes 的執(zhí)行的過程是:

  • Lexing:詞法掃描分析,將源文件轉(zhuǎn)換成 token 流;
  • Parsing:語法分析,在此階段生成 op arrays。
  • 2)PHP7 中在語法分析階段不再直接生成 op arrays,而是先生成 AST,所以過程多了一步:

  • Lexing:詞法掃描分析,將源文件轉(zhuǎn)換成 token 流;
  • Parsing:語法分析,從 token 流生成抽象語法樹;
  • Compilation:從抽象語法樹生成 op arrays。
  • 添加了抽象語法樹:內(nèi)存的使用增加了,但是執(zhí)行時(shí)間上卻有所降低

    AST在PHP編譯過程作為一個(gè)中間件的角色,替換原來直接從解釋器吐出opcode的方式,讓解釋器(parser)和編譯器(compliler)解耦,可以減少一些Hack代碼,同時(shí),讓實(shí)現(xiàn)更容易理解和可維護(hù)

    2?Natice TLS

    ?

    PHP在多線程模式下,需要解決“線程安全”(TS,Thread?Safe)的問題,因?yàn)榫€程是共享進(jìn)程的內(nèi)存空間的,所以每個(gè)線程本身需要通過某種方式,構(gòu)建私有的空間來保存自己的私有數(shù)據(jù),避免和其他線程相互污染。

    而PHP5采用的方式,就是維護(hù)一個(gè)全局大數(shù)組,為每一個(gè)線程分配一份獨(dú)立的存儲(chǔ)空間,線程通過各自擁有的key值來訪問這個(gè)全局?jǐn)?shù)據(jù)組。而這個(gè)獨(dú)有的key值在PHP5中需要傳遞給每一個(gè)需要用到全局變量的函數(shù),PHP7認(rèn)為這種傳遞的方式并不友好,并且存在一些問題。因而,嘗試采用一個(gè)全局的線程特定變量來保存這個(gè)key值。

    3 指定參數(shù) 返回值類型

    PHP語言一個(gè)非常重要的特點(diǎn)就是“弱類型”,它讓PHP的程序變得非常容易編寫.

    PHP7可選的方式支持類型定義,除此之外,還引入了一個(gè)開關(guān)指令declare(strict_type=1);,當(dāng)這個(gè)指令一旦開啟,將會(huì)強(qiáng)制當(dāng)前文件下的程序遵循嚴(yán)格的函數(shù)傳參類型和返回類型。

    4 zval 結(jié)構(gòu)的變化

    ?

    在PHP5的時(shí)候, 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;
  • };
  • 首先這個(gè)結(jié)構(gòu)體的大小是(在64位系統(tǒng))24個(gè)字節(jié), 我們仔細(xì)看這個(gè)zval.value聯(lián)合體, 其中zend_object_value是最大的長板, 它導(dǎo)致整個(gè)value需要16個(gè)字節(jié), 這個(gè)應(yīng)該是很容易可以優(yōu)化掉的, 比如把它挪出來, 用個(gè)指針代替,因?yàn)楫吘笽S_OBJECT也不是最最常用的類型.

    第二, 這個(gè)結(jié)構(gòu)體的每一個(gè)字段都有明確的含義定義, 沒有預(yù)留任何的自定義字段, 導(dǎo)致在PHP5時(shí)代做很多的優(yōu)化的時(shí)候, 需要存儲(chǔ)一些和zval相關(guān)的信息的時(shí)候, 不得不采用其他結(jié)構(gòu)體映射, 或者外部包裝后打補(bǔ)丁的方式來擴(kuò)充zval, 比如5.3的時(shí)候新引入專門解決循環(huán)引用的GC, 它不得采用如下的比較hack的做法

    第三, PHP的zval大部分都是按值傳遞, 寫時(shí)拷貝的值, 但是有倆個(gè)例外, 就是對(duì)象和資源, 他們永遠(yuǎn)都是按引用傳遞, 這樣就造成一個(gè)問題, 對(duì)象和資源在除了zval中的引用計(jì)數(shù)以外, 還需要一個(gè)全局的引用計(jì)數(shù), 這樣才能保證內(nèi)存可以回收. 所以在PHP5的時(shí)代, 以對(duì)象為例, 它有倆套引用計(jì)數(shù), 一個(gè)是zval中的, 另外一個(gè)是obj自身的計(jì)數(shù):

    ?

    第四, 我們知道PHP中, 大量的計(jì)算都是面向字符串的, 然而因?yàn)橐糜?jì)數(shù)是作用在zval的, 那么就會(huì)導(dǎo)致如果要拷貝一個(gè)字符串類型的zval, 我們別無他法只能復(fù)制這個(gè)字符串. 當(dāng)我們把一個(gè)zval的字符串作為key添加到一個(gè)數(shù)組里的時(shí)候, 我們別無他法只能復(fù)制這個(gè)字符串. 雖然在PHP5.4的時(shí)候, 我們引入了INTERNED STRING, 但是還是不能根本解決這個(gè)問題.

    還比如, PHP中大量的結(jié)構(gòu)體都是基于Hashtable實(shí)現(xiàn)的, 增刪改查Hashtable的操作占據(jù)了大量的CPU時(shí)間, 而字符串要查找首先要求它的Hash值, 理論上我們完全可以把一個(gè)字符串的Hash值計(jì)算好以后, 就存下來, 避免再次計(jì)算等等

    第五, 這個(gè)是關(guān)于引用的, PHP5的時(shí)代, 我們采用寫時(shí)分離, 但是結(jié)合到引用這里就有了一個(gè)經(jīng)典的性能問題:

    第六, 也是最重要的一個(gè), 為什么說它重要呢? 因?yàn)檫@點(diǎn)促成了很大的性能提升, 我們習(xí)慣了在PHP5的時(shí)代調(diào)用MAKE_STD_ZVAL在堆內(nèi)存上分配一個(gè)zval, 然后對(duì)他進(jìn)行操作, 最后呢通過RETURN_ZVAL把這個(gè)zval的值”copy”給return_value, 然后又銷毀了這個(gè)zval, 比如pathinfo這個(gè)函數(shù):

    ?

    5 異常處理

    PHP 5 的 try ... catch ... finally 無法處理傳統(tǒng)錯(cuò)誤,如果需要,你通常會(huì)考慮用 set_error_handler() 來 Hack 一下。但是仍有很多錯(cuò)誤類型是 set_error_handler() 捕捉不到的

    ?PHP 7引入 Throwable 接口,錯(cuò)誤及異常都實(shí)現(xiàn)了 Throwable,無法直接實(shí)現(xiàn) Throwable,但可以擴(kuò)展 \Exception 和 \Error 類。可以用 Throwable 捕捉異常跟錯(cuò)誤。\Exception 是所有PHP及用戶異常的基類;\Error 是所有內(nèi)部PHP錯(cuò)誤的基類。

    $name = "Tony";

    try {

    ??? $name = $name->method();

    } catch (\Error $e) {

    ??? echo "出錯(cuò)消息 --- ", $e->getMessage(), PHP_EOL;

    }

    ?

    try {

    ??? $name = $name->method();

    } catch (\Throwable $e) {

    ??? echo "出錯(cuò)消息 --- ", $e->getMessage(), PHP_EOL;

    }

    ?

    try {

    ??? intdiv(5, 0);

    } catch (\DivisionByZeroError $e) {

    ??? echo "出錯(cuò)消息 --- ", $e->getMessage(), PHP_EOL;

    }

    ?

    6 hashtable 的變化

    7 執(zhí)行器

    8 新的參數(shù)解析方式

    PHP5? 對(duì)應(yīng)的參數(shù)解析 zend_parse_parament,

    PHP7對(duì)應(yīng)的參數(shù)解析:fast_zpp??

    總結(jié)

    以上是生活随笔為你收集整理的php7和PHP5对比的新特性和性能优化的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。