激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - PHP教程 - 百度工程師講PHP函數(shù)的實現(xiàn)原理及性能分析(一)

百度工程師講PHP函數(shù)的實現(xiàn)原理及性能分析(一)

2020-09-24 17:28PHP教程網(wǎng) PHP教程

這篇文章主要介紹了百度工程師講PHP函數(shù)的實現(xiàn)原理及性能分析(一),需要的朋友可以參考下

前言

在任何語言中,函數(shù)都是最基本的組成單元。對于php的函數(shù),它具有哪些特點?函數(shù)調(diào)用是怎么實現(xiàn)的?php函數(shù)的性能如何,有什么使用建議?本文將從原理出發(fā)進行分析結(jié)合實際的性能測試嘗試對這些問題進行回答,在了解實現(xiàn)的同時更好的編寫php程序。同時也會對一些常見的php函數(shù)進行介紹。

php函數(shù)的分類

在php中,橫向劃分的話,函數(shù)分為兩大類: user function(內(nèi)置函數(shù)) 和internal function(內(nèi)置函數(shù))。前者就是用戶在程序中自定義的一些函數(shù)和方法,后者則是php本身提供的各類庫函數(shù)(比如sprintf、array_push等)。用戶也可以通過擴展的方法來編寫庫函數(shù),這個將在后面介紹。對于user function,又可以細分為function(函數(shù))和method(類方法),本文中將就這三種函數(shù)分別進行分析和測試。

php函數(shù)的實現(xiàn)

一個php函數(shù)最終是如何執(zhí)行,這個流程是怎么樣的呢?
要回答這個問題,我們先來看看php代碼的執(zhí)行所經(jīng)過的流程。

百度工程師講PHP函數(shù)的實現(xiàn)原理及性能分析(一)

從圖1可以看到,php實現(xiàn)了一個典型的動態(tài)語言執(zhí)行過程:拿到一段代碼后,經(jīng)過詞法解析、語法解析等階段后,源程序會被翻譯成一個個指令(opcodes),然后ZEND虛擬機順次執(zhí)行這些指令完成操作。Php本身是用c實現(xiàn)的,因此最終調(diào)用的也都是c的函數(shù),實際上,我們可以把php看做是一個c開發(fā)的軟件。通過上面描述不難看出,php中函數(shù)的執(zhí)行也是被翻譯成了opcodes來調(diào)用,每次函數(shù)調(diào)用實際上是執(zhí)行了一條或多條指令。

對于每一個函數(shù),zend都通過以下的數(shù)據(jù)結(jié)構(gòu)來描述

復制代碼 代碼如下:


typedef union _zend_function {
zend_uchar type; /* MUST be the first element of this struct! */
struct {
zend_uchar type; /* never used */
char *function_name;
zend_class_entry *scope;
zend_uint fn_flags;
union _zend_function *prototype;
zend_uint num_args;
zend_uint required_num_args;
zend_arg_info *arg_info;
zend_bool pass_rest_by_reference;
unsigned char return_reference;
} common;

 

zend_op_array op_array;
zend_internal_function internal_function;
} zend_function;


typedef struct _zend_function_state {
HashTable *function_symbol_table;
zend_function *function;
void *reserved[ZEND_MAX_RESERVED_RESOURCES];
} zend_function_state;

 

其中type標明了函數(shù)的類型:用戶函數(shù)、內(nèi)置函數(shù)、重載函數(shù)。Common中包含函數(shù)的基本信息,包括函數(shù)名,參數(shù)信息,函數(shù)標志(普通函數(shù)、靜態(tài)方法、抽象方法)等內(nèi)容。另外,對于用戶函數(shù),還有一個函數(shù)符號表,記錄了內(nèi)部變量等,這個將在后面詳述。 Zend維護了一個全局function_table,這是一個大的hahs表。函數(shù)調(diào)用的時候會首先根據(jù)函數(shù)名從表中找到對應的zend_function。當進行函數(shù)調(diào)用時候,虛擬機會根據(jù)type的不同決定調(diào)用方法, 不同類型的函數(shù),其執(zhí)行原理是不相同的 。

內(nèi)置函數(shù)

內(nèi)置函數(shù),其本質(zhì)上就是真正的c函數(shù),每一個內(nèi)置函數(shù),php在最終編譯后都會展開成為一個名叫zif_xxxx的function,比如我們常見的sprintf,對應到底層就是zif_sprintf。Zend在執(zhí)行的時候,如果發(fā)現(xiàn)是內(nèi)置函數(shù),則只是簡單的做一個轉(zhuǎn)發(fā)操作。
Zend提供了一系列的api供調(diào)用,包括參數(shù)獲取、數(shù)組操作、內(nèi)存分配等。內(nèi)置函數(shù)的參數(shù)獲取,通過zend_parse_parameters方法來實現(xiàn),對于數(shù)組、字符串等參數(shù),zend實現(xiàn)的是淺拷貝,因此這個效率是很高的。可以這樣說,對于php內(nèi)置函數(shù),其效率和相應c函數(shù)幾乎相同,唯一多了一次轉(zhuǎn)發(fā)調(diào)用。

內(nèi)置函數(shù)在php中都是通過so的方式進行動態(tài)加載,用戶也可以根據(jù)需要自己編寫相應的so,也就是我們常說的擴展。ZEND提供了一系列的api供擴展使用

用戶函數(shù)

和內(nèi)置函數(shù)相比,用戶通過php實現(xiàn)的自定義函數(shù)具有完全不同的執(zhí)行過程和實現(xiàn)原理。如前文所述,我們知道php代碼是被翻譯成為了一條條opcode來執(zhí)行的,用戶函數(shù)也不例外,實際中每個函數(shù)對應到一組opcode,這組指令被保存在zend_function中。于是,用戶函數(shù)的調(diào)用最終就是對應到一組opcodes的執(zhí)行。

》》局部變量的保存及遞歸的實現(xiàn)

我們知道,函數(shù)遞歸是通過堆棧來完成的。在php中,也是利用類似的方法來實現(xiàn)。Zend為每個php函數(shù)分配了一個活動符號表(active_sym_table),記錄當前函數(shù)中所有局部變量的狀態(tài)。所有的符號表通過堆棧的形式來維護,每當有函數(shù)調(diào)用的時候,分配一個新的符號表并入棧。當調(diào)用結(jié)束后當前符號表出棧。由此實現(xiàn)了狀態(tài)的保存和遞歸。
對于棧的維護,zend在這里做了優(yōu)化。預先分配一個長度為N的靜態(tài)數(shù)組來模擬堆棧,這種通過靜態(tài)數(shù)組來模擬動態(tài)數(shù)據(jù)結(jié)構(gòu)的手法在我們自己的程序中也經(jīng)常有使用,這種方式避免了每次調(diào)用帶來的內(nèi)存分配、銷毀。ZEND只是在函數(shù)調(diào)用結(jié)束時將當前棧頂?shù)姆柋頂?shù)據(jù)clean掉即可。因為靜態(tài)數(shù)組長度為N,一旦函數(shù)調(diào)用層次超過N,程序不會出現(xiàn)棧溢出,這種情況下zend就會進行符號表的分配、銷毀,因此會導致性能下降很多。在zend里面,N目前取值是32。因此,我們編寫php程序的時候,函數(shù)調(diào)用層次最好不要超過32。當然,如果是web應用,本身可以函數(shù)調(diào)用層次的深度。

》》參數(shù)的傳遞 和內(nèi)置函數(shù)調(diào)用zend_parse_params來獲取參數(shù)不同,用戶函數(shù)中參數(shù)的獲取是通過指令來完成的。函數(shù)有幾個參數(shù)就對應幾條指令。具體到實現(xiàn)上就是普通的變量賦值。通過上面的分析可以看出,和內(nèi)置函數(shù)相比,由于是自己維護堆棧表,而且每條指令的執(zhí)行也是一個c函數(shù),用戶函數(shù)的性能相對會差很多,后面會有具體的對比分析。因此,如果一個功能有對應php內(nèi)置函數(shù)實現(xiàn)的盡量不要自己重新寫函數(shù)去實現(xiàn)。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 久国久产久精永久网页 | 亚洲一区在线视频观看 | 国产成人在线一区 | 国产精品一区二区三区在线 | 精品国产91久久久久久浪潮蜜月 | 深夜福利视频绿巨人视频在线观看 | 日韩精品免费看 | 综合精品 | 免费国产在线观看 | 吾色视频 | 欧美成人免费电影 | 国产亚洲精品精 | 免费观看一区二区三区视频 | av在线免费网 | 99久久99视频| 欧美在线黄色 | 一级做a爱性色毛片免费1 | 国产在线看一区 | 久久av一区二区 | 亚洲射吧 | 日本不卡一区二区三区在线 | 国产伦精品一区二区三区 | 日韩黄色片免费看 | 美国av免费看 | 精品成人av一区二区三区 | 国产成人在线观看网站 | 国产精品剧情一区二区在线观看 | 国产分类视频 | 《97色伦在色在线播放》 | 国产噜噜噜噜久久久久久久久 | 日韩精品中文字幕在线观看 | 国产成人综合在线观看 | 国产精品成人免费一区久久羞羞 | 成人国产在线看 | 日韩视频一区二区三区在线观看 | av免费不卡国产观看 | 哪里可以看免费的av | 在线中文字幕网站 | 欧美一级视频在线观看 | 久草在线综合网 | 毛片网站视频 |