php代碼性能調優profile利器xhprof工作原理淺析

發表于:2013-01-30來源:Csdn作者:yzongyu點擊數: 標簽:xhprof
php代碼性能調優profile利器xhprof工作原理淺析。 xhprof是php的第三方擴展,工作在zend層,以動態加載的方式被加載。php在解釋執行的過程中,首先被解釋成對應的token碼,而后,編譯成字節碼(這里的字節碼不是機器碼,在PHP里面稱其為opcode碼)。xhprof就在php被加載

  xhprof的工作原理

  xhprof是php的第三方擴展,工作在zend層,以動態加載的方式被加載。php在解釋執行的過程中,首先被解釋成對應的token碼,而后,編譯成字節碼(這里的字節碼不是機器碼,在PHP里面稱其為opcode碼)。xhprof就在php被加載,loading,引起自身extension的時候一起被加載,解釋,編譯。

  xhprof本身通過對zend層函數處理相關的結構體的定義,比如:

  zend_module_entry xhprof_module_entry = {

  #if ZEND_MODULE_API_NO >= 20010901

  STANDARD_MODULE_HEADER,

  #endif

  "xhprof", /* Name of the extension */

  xhprof_functions, /* List of functions exposed */

  PHP_MINIT(xhprof), /* Module init callback */

  PHP_MSHUTDOWN(xhprof), /* Module shutdown callback */

  PHP_RINIT(xhprof), /* Request init callback */

  PHP_RSHUTDOWN(xhprof), /* Request shutdown callback */

  PHP_MINFO(xhprof), /* Module info callback */

  #if ZEND_MODULE_API_NO >= 20010901

  XHPROF_VERSION,

  #endif

  STANDARD_MODULE_PROPERTIES

  };

  來完成xhprof自定義的函數的初始化,完成xhprof本身的callback機制的注冊。

  在安裝xhprof的過程中,我們需要去定義xhprof報告的輸出目錄,并且我們設置的時候,變量的名稱只能是:xhprof.output_dir原因就在于在xhprof.c的文件中,對于php_ini_entry的設定就是

  PHP_INI_BEGIN()

  /* output directory:

  * Currently this is not used by the extension itself.

  * But some implementations of iXHProfRuns interface might

  * choose to save/restore XHProf profiler runs in the

  * directory specified by this ini setting.

  */

  PHP_INI_ENTRY("xhprof.output_dir", "", PHP_INI_ALL, NULL)

  PHP_INI_END()這里完成的對php.ini里有關xhprof的配置節的定義方式和方法。相關解釋如下:

  如果想要為你的模塊創建一個 .ini 文件的配置節,可以使用宏 PHP_INI_BEGIN() 來標識這個節的開始,并用 PHP_INI_END() 表示該配置節已經結束。然后在兩者之間我們用 PHP_INI_ENTRY() 來創建具體的配置項。HP_INI_ENTRY() 總共接收 4 個參數:配置項名稱、初始值、改變這些值所需的權限以及在值改變時用于接收通知的函數句柄。配置項名稱和初始值必須是一個字符串,即使它們是一個整數。HP_INI_SYSTEM 只允許在 php.ini 中改變這些值;PHP_INI_USER 允許用戶在運行時通過像 .htaccess 這樣的附加文件來重寫其值;而 PHP_INI_ALL 則允許隨意更改。

  前面提到xhprof是在config.m4里面,作為$ext_shared的方式被動態加載進入zend層工作的,所以,這里還需要用zend_get_module進行一些處理。zend_get_module的作用為:

  ZEND_GET_MODULE (extension_name)

  Description:

  Provides additional C code used if you want to build a dynamic loaded extension.

  到這里,如果xhprof安裝正常,那么就已經完成了php在啟動的過程中,xhprof作為extension,被加載的方式的定義,和具體的方法的定義了。

  前面大體是xhprof在安裝后,是工作在哪一層?以何種方式被引入php?怎么被引入的?相關理解和解釋,下面再看看xhprof是怎么收集到函數的執行性能profile數據的,例如cpu、memory的使用等信息數據

  PHP_FUNCTION(xhprof_enable) {

  long xhprof_flags = 0; /* XHProf flags */

  zval *optional_array = NULL; /* optional array arg: for future use */

  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,

  "|lz", &xhprof_flags, &optional_array) == FAILURE) {

  return;

  }

  hp_get_ignored_functions_from_arg(optional_array);

  這個函數里面是對xhprof_enable函數體的實現,在我們需要對一個函數進行xhprof的時候,需要在最開始進行xhprof_enable()的調用,enable里面可以傳參數也可以默認為空,這里zend_parse_parameters的參數中,"ZEND_NUM_ARGS() TSRMLS_CC"部分基本是固定打法,接著的部分 代表參數的相應類型。在這里"|lz"的意思是$xhprof_flags is long typeof,$optional_array is array typeof).

  zend_parse_parameters 詳解

  自動生成的PHP函數周圍包含了一些注釋,這些注釋用于自動生成代碼文檔和vi、Emacs等編輯器的代碼折疊。函數自身的定義使用了宏PHP_FUNCTION(),該宏可以生成一個適合于Zend引擎的函數原型。邏輯本身分成語義各部分,取得調用函數的參數和邏輯本身。為了獲得函數傳遞的參數,可以使用zend_parse_parameters()API函數

  所以如果獲取xhprof_enable傳入的參數如果失敗,則會直接return。到下面,則是對hp_get_ignored_functions_from_arg的調用,看名字應該是對要忽略的函數名的獲取,從該函數的本身內容

  static void hp_get_ignored_functions_from_arg(zval *args) {

  if (args != NULL) {

  zval *zresult = NULL;

  zresult = hp_zval_at_key("ignored_functions", args);

  hp_globals.ignored_function_names = hp_strings_in_zval(zresult);

  } else {

  hp_globals.ignored_function_names = NULL;

  }

  }可以看出,這個函數的確是對需要忽略的函數名的獲取。

  這里插一腳,php之所以可以在使用變量前不需要對該變量進行提前定義,是因為在php的zend引擎中有這么一個東西zval,在php里面,zend用它來作為一個容器,來處理所有的外部變量,還是直接貼一段代碼,大家一起來看

原文轉自:http://blog.csdn.net/yzongyu/article/details/8457209

国产97人人超碰caoprom_尤物国产在线一区手机播放_精品国产一区二区三_色天使久久综合给合久久97