今天分享個前天剛剛做的小工具, 代碼可以在github上找到: php-valgrind. 這個工具主要是為PHP腳本提供了可以在腳本中開啟Valgrind(嚴格說是Callgrind)的Profile能力.
一般來說, 我們用Callgrind的時候, 如果要分析某一個函數, 可以通過toggle-collect=”函數名”, 來告訴Callgrind在進入這個函數的時候開始Profile. 但是這樣沒有辦法分析具體某一段代碼..
其實Callgrind提供了一個機制, 可以讓我們在代碼中控制何時開啟: CALLGRIND_TOGGLE_COLLECT
比如:
#include <stdio.h>#include <valgrind/callgrind.h>void foo(int a[100]) { int i = 0;}int main (int argc, char **argv) { int i, a[100]; CALLGRIND_START_INSTRUMENTATION; CALLGRIND_TOGGLE_COLLECT; for (i=0; i<100; i++) { a[i] = 2; } CALLGRIND_TOGGLE_COLLECT; CALLGRIND_STOP_INSTRUMENTATION; return;}
然后, 編譯成a.out以后, 我們就可以分析具體的這個循環代碼斷的相關Profile信息: www.it165.net
$ valgrind --tool=callgrind --collect-atstart=no --instr-atstart=no ./a.out
之后生成的callgrind.out就可以被callgrind_annotate, kcachegrind等工具來分析了
$callgrind_annotate callgrind.out.27538//OUTPUT:-------------------------------------------------------------------------------- Ir---------------------------------------617 PROGRAM TOTALS--------------------------------------- Ir file:function---------------------------------------617 test.c:main [***dev/a.out]
是不是很方便呢?
但是呢, 有的時候, 比如我們做擴展, 或者其他的一類內部的性能分析的時候. 需要在PHP腳本也能做這樣的觸發. 就沒有辦法了. 于是我就寫了這個小工具php-valgrind, 裝好這個擴展以后, 來看個例子:
<?php$a = array();callgrind_toggle();for ($i=0;$i<1000;$i++) { $a[$i] = 2;}callgrind_toggle();
然后我們開始分析:
$valgrind --tool=callgrind --collect-atstart=no --instr-atstart=no php /tmp/1.php
然后我們分析下輸出:
------------------------- Ir--------------------------2,361,260 PROGRAM TOTALS//以下省略
然后讓我們用qcachegrind(帶gui的callgrind分析工具), 來看看:
可見, PHP要實現同樣的功能需要的各種代碼數相比C語言來說, 那可是多了N倍的(所以當然要比C慢了.. 嘿嘿, 再次申明: “C語言是最好的語言, 沒有之一!”)
好了工具介紹完畢, 大家有興趣的可以去玩玩, 這個工具還可以用來讓我們了解, 我們的一個PHP代碼, 會觸發調用那些底層的函數, 或者系統調用等等, Enjoy~
鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。
新聞熱點
疑難解答