首頁  >  文章  >  後端開發  >  全方位解讀php8.0版本優化與改進

全方位解讀php8.0版本優化與改進

Guanhui
Guanhui轉載
2020-06-29 09:51:518012瀏覽

全方位解讀php8.0版本優化與改進

除非你一直住在一塊石頭下,或活在過去,否則你會意識到JIT正在進入PHP 8:投票今天悄悄結束,絕大多數人贊成合併到PHP8,所以,這是正式的,本文全方位解讀php8.0版本優化與改進。

PHP8 官方宣布《PHP 8 來了! PHP團隊發布了首個測試版本Alpha1

現在,坐下來閱讀下面這篇顛覆神話的文章,我們將澄清一些關於JIT是什麼、它將帶來什麼好處的困惑,並深入研究它是如何工作的(但只是一點點,因為我不想讓你感到無聊)。

因為我不知道我在和誰說話,所以我會從簡單的問題開始,一直到複雜的問題,如果你已經確定你知道標題中問題的答案,你可以跳過那部分。 。 。

什麼是JIT?

PHP實作了一個虛擬機,一種虛擬處理器,我們稱之為Zend VM。 PHP將人類可讀的腳本編譯成虛擬機器能理解的指令(我們稱之為操作碼),這個執行階段就是我們所說的「編譯時」。在執行的「運行時」階段,虛擬機器(Zend VM)執行程式碼的指令(操作碼)。

這一切運作得很好,像APC(過去)和OPCache(現在)這樣的工具可以快取程式碼的指令(操作碼),以便「編譯時」只在必須的時候發生。

首先,有一行程式碼解釋了什麼是JIT:

Just-in-time 是一種編譯器策略,它接受程式碼的中間表示形式,並在運行時將其轉換為依賴體系結構的機器程式碼,以便及時執行。

在PHP中,這表示JIT將為Zend VM產生的指令作為中間表示,並發出依賴體系結構的機器碼,因此程式碼的宿主不再是ZendVM,而是CPU。

為什麼PHP需要JIT?

在PHP 7.0之前,PHP內部社群關注的焦點是效能,這是由Facebook的HHVM計畫帶來的良性競爭所帶來的。 PHP 7.0中的大部分核心變更都包含在PHPNG補丁中,這大大改進了PHP在其核心上利用記憶體和CPU的方式,從那時起,我們每個人都被迫專注於效能。

自PHP 7.0以來,已經有了一些效能改進,HashTable (PHP的核心資料結構)的最佳化,某些操作碼的Zend VM的專門化,某些序列的編譯器的專門化,以及對OPCache的最佳化器元件的不斷改進。 。 。除此之外還有很多其他的,太無聊了。

這是一個殘酷的事實,這些優化只能帶我們到目前為止,我們正在迅速接近,或者可能已經遇到了磚牆,在我們的能力,以進一步改善它。

注意:當我們說「我們不能再改進了」時,我們真正的意思是,「我們必須做出取捨,以進一步改進它不再看起來有吸引力」。 。 。每當我們討論效能優化時,我們都在討論權衡。通常,在簡單性和效能之間進行權衡。我們都想認為最簡單的程式碼是最快的程式碼,但在現代C程式設計的世界中,情況並非如此。最快的程式碼通常是準備利用依賴體系結構的內部函數或依賴平台(編譯器)的內部函數的程式碼。簡單並不能保證最好的效能。 。 。

此時,PHP的JIT功能似乎是從PHP獲得更多效能的最佳方法。

JIT會讓我的網站更快嗎?

很可能,也不明顯。

也許不是您期望的答案:在一般情況下,用PHP編寫的應用程式是I/O綁定的,JITCPU綁定的程式碼上工作得最好。

「I/O和CPU綁定」到底是什麼意思?

當我們想要描述一段程式碼或一個應用程式的一般效能特徵時,我們使用術語I/O綁定CPU綁定

最簡單的說法是:

  • 如果我們能夠改進(減少、最佳化)它所做的I/O,那麼一段I/O綁定的程式碼將會運行得更快。

  • 如果我們能夠改進(減少、最佳化)CPU正在執行的指令,或是(神奇地)提高CPU的時脈速度,那麼一段CPU限制的程式碼就會運作得更快:)

  • 一段程式碼或一個應用程式可以是I/O綁定、CPU綁定,或與CPU和I/O同等綁定。

  • 一般来说,PHP应用程序往往是I/O绑定的——减慢它们速度的是它们正在执行的I/O——连接、读取和写入数据库、缓存、文件、套接字等等。

CPU绑定的PHP是什么样子的?

由于大多数PHP应用程序的性质,许多PHP程序员并不熟悉CPU绑定代码——他们的工作往往是连接到某个数据库,或者可能是一个缓存,做一些轻量级的工作,并输出html/json/xml响应。

您可能会环顾代码库,发现许多与I/O无关的代码,甚至调用与I/O完全断开连接的函数的代码,并且会感到困惑,我似乎是在暗示这并没有使您的应用程序CPU受到限制,即使处理非I/O的代码行数可能比I/O多。

PHP实际上相当快,它是世界上解释速度最快的语言之一。Zend VM调用与I/O无关的函数和在机器代码中进行相同的调用之间没有显著的区别。

这显然是有区别的,但事实是,机器代码有一个调用约定,Zend VM有一个调用约定,机器代码有一个序言,Zend VM有一个序言:在Zend操作码中调用某个c_level_function()还是机器代码对调用应用程序的性能没有显著影响-尽管这似乎对那个电话有很大的影响。

注意:调用约定大致是指在进入另一个函数之前执行的一系列指令,序言是指在进入另一个函数时执行的一系列指令:在这两种情况下,调用约定都将参数推送到堆栈上,序言将它们从堆栈中弹出。

循环、尾调用和X呢?我听说你问过:PHP实际上非常聪明,启用了OPCache的优化器组件,你的代码就好像被魔法转化成了你能编写的最有效的形式。

现在需要注意的是,JIT不会改变Zend函数的调用约定,而不是VM建立的约定-Zend必须能够在任何时候在JIT和VM模式之间切换,因此决定保留VM建立的调用约定。因此,当JIT运行时,随处可见的那些调用并没有明显地加快速度。

如果您想了解CPU绑定的PHP代码是什么样子的,请查看Zend/bench.php文件... 这显然是一个极限的CPU代码示例,但它应该让我们知道JIT真正的亮点是在数学领域。

PHP是否为加快数学速度做出了最终的权衡?

不,我们这样做是为了扩大PHP的范围,而且相当大。

在这个非常偏颇的PHP开发人员看来,如果你在2019年是一名web程序员,你还没有考虑在下一个项目中使用PHP,那么你做的web是错误的。

在PHP中提高更快地执行数学的能力,乍一看,似乎是一个非常狭窄的范围。

然而,这实际上为机器学习、3d渲染、2d(gui)渲染和数据分析(仅举几个例子)打开了大门。

为什么我们不能在PHP 7.4中使用它呢?

我刚刚把JIT称为“最终的权衡”,我认为它是:它可以说是有史以来最复杂的编译器策略之一,也许是最复杂的。引入JIT就是引入相当的复杂性。

如果你问Dmitry(JIT的作者)他是否让PHP变得复杂,他会说“不,我讨厌复杂性”(这是一个直接的引语)。

归根结底,复杂是我们所不了解的,而目前,真正了解JIT实现的内部开发人员(不到几个)很少。

PHP 7.4的发展很快,合并到php7.4中会给我们留下一个PHP版本,只有不到几个人可以调试、修复或改进(在任何实际意义上)。对于那些对合并到PHP 7.4投反对票的人来说,这种情况是不可接受的。

在从现在到PHP 8的这段时间里,我们中的许多人将在业余时间努力理解JIT:

我们仍然有一些要实现的特性和需要为php8重写的工具,首先我们必须理解JIT。我们需要这一次,并非常感谢大多数选民认为适合把它交给我们。

复杂并不是可怕的同义词:

复杂可以是美丽的,就像星云一样,JIT就是那种复杂。原则上,你可以完全理解某件复杂的事情,并且只在表面上的复杂程度上稍微降低一点。换句话说,即使有20个内部开发人员和Dmitry一样熟悉JIT,它也不会真正改变JIT的复杂性。

PHP的开发速度会减慢吗?

没有理由认为会这样。我们有足够的时间可以满怀信心地说,到PHP 8普遍可用时,我们中已经有足够多的人熟悉JIT,至少在修复bug和推动PHP向前发展方面能够像今天一样发挥作用。

當試圖將這一點與JIT本質上是複雜的觀點聯繫起來時,請考慮我們花在引入新特性上的大部分時間實際上是花在討論該特性上的。對於大多數功能,甚至修復,程式碼可能需要幾分鐘或幾小時的編寫時間,而討論則需要幾週或幾個月的時間。在極少數情況下,一個特性的程式碼可能需要幾個小時或幾天的時間來編寫,但在這些極少數情況下,討論總是需要更長的時間。

PHP8 詳細解析參考《PHP8 新特性之 JIT 圖文詳解》《PHP 8 效能究竟有多大的提升?

本文由php中文網直譯自:https://blog.krakjoe.ninja/2019/03/php-gr8.html

以上是全方位解讀php8.0版本優化與改進的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:krakjoe。如有侵權,請聯絡admin@php.cn刪除