PHP Performance Profiling
The basic report shown above is useful for getting an overview of the script's execution, but you also can pass other options to pprofp that tell it to format the report in different ways. Simply call it using pprofp <option> <tracefile>, using one or more of these options:
-a: sort by alphabetic names of subroutines.
-l: sort by number of calls to subroutines
-m: sort by memory used in a function call.
-r: sort by real time spent in subroutines.
-R: sort by real time spent in subroutines (inclusive of child calls).
-s: sort by system time spent in subroutines.
-S: sort by system time spent in subroutines (inclusive of child calls).
-u: sort by user time spent in subroutines.
-U: sort by user time spent in subroutines (inclusive of child calls).
-v: sort by average amount of time spent in subroutines.
-z: sort by user+system time spent in subroutines. (default)
-c: display real time elapsed alongside call tree.
-i: suppress reporting for PHP built-in functions
-O <cnt>: specify maximum number of subroutines to display. (default 15)
-t: display compressed call tree.
-T: display uncompressed call tree.
If you have a lot of functions (subroutines) in your script, it may be helpful to sort by number of calls (pprofp -l <tracefile>) or by memory used (pprofp -m <tracefile>) to see quickly where the bottlenecks are.
Although the function call report probably is the most immediately useful one for finding bottlenecks, one of the funkiest options in the pprofp script is the ability to output a function call tree. A function call tree essentially is a step-by-step list of each executed function, indented to show function nesting.
You can output a function call tree with the -t or -T options, like this:
pprofp -t /var/log/php4-apd/pprof.15507
which output something like this for my Squirrelmail example:
main require_once php_self require_once (2x) session_is_registered require_once require_once require_once (3x) require_once (2x) require_once require_once require_once require_once is_array use_plugin file_exists include_once function_exists ... etc
As you can see, a require_once was performed and inside that a php_self was executed. Then another require_once executed session_is_registered, followed by another require_once and so on. Basically, the function call tree is like a little window into the Zend Engine, allowing you to watch the sequence of events that take place when your Web application is run.
If you do much object-oriented development, you may find that you rapidly lose track of what's actually going on inside some classes and methods. It's tempting to think of classes as a black box, because that's how we're taught to use them. But, when optimizing a complex Web application, you need to know what's actually going on inside each one, or you may have performance bottlenecks you do not even notice.
APD provides quite a number of functions that you can use to help profile and debug your code. Experiment with these to see the gory internal details of what the Zend Engine is doing with your script, but note that some of them now are deprecated for PHP4.3+:
apd_set_pprof_trace(): the most useful APD function as far as profiling is concerned, this dumps a tracefile named pprof.<pid> in your apd.dumpdir. The tracefile is a machine-parsable output file that can be processed with the pprofp <tracefile> command.
apd_set_session_trace(N): similar to apd_set_pprof_trace(), it dumps a human-readable session trace named apd_dump_<pid> in your apd.dumpdir. This is the old way of doing things, noted here because it still works (for now). It's been deprecated, so it's better to use a pproftrace instead. N is an integer that sets the items to be traced; for now, use a value of 99 to turn on all implemented options.
array apd_callstack(): returns the current call stack at that stage of execution as an array.
apd_cluck([string warning[,string line delimiter]): behaves like Perl's Carp::cluck module. Throws a warning and a callstack. The default line delimiter is <BR />\n. This function is deprecated for users of PHP4.3+; use the internal debug_backtrace() and debug_print_backtrace()instead.
apd_croak([string error[, string line delimiter]]): behaves like Perl's Carp::croak module. Throws an error, a callstack and then exits. The default line delimiter is <BR />\n'. This function is deprecated for users of PHP4.3+; use the internal debug_backtrace() and debug_print_back-trace() instead.
array apd_dump_regular_resources(): returns all current regular resources as an array.
array apd_dump_persistent_resources(): returns all persistent resources as an array.
override_function(string func_name, string func_args, string func_code): syntax is similar to create_function(), overrides built-in functions (replaces them in the symbol table).
rename_function(string orig_name, string new_name): renames orig_name to new_name in the global function_table. Useful for temporarily overriding built-in functions.
Special Reports: DevOps
Have projects in development that need help? Have a great development operation in place that can ALWAYS be better? Regardless of where you are in your DevOps process, Linux Journal can help!
With deep focus on Collaborative Development, Continuous Testing and Release & Deployment, we offer here the DEFINITIVE DevOps for Dummies, a mobile Application Development Primer, advice & help from the experts, plus a host of other books, videos, podcasts and more. All free with a quick, one-time registration. Start browsing now...
- The Ubuntu Conspiracy
- Vigilante Malware
- Disney's Linux Light Bulbs (Not a "Luxo Jr." Reboot)
- Vagrant Simplified
- Libreboot on an X60, Part I: the Setup
- Bluetooth Hacks
- Dealing with Boundary Issues
- System Status as SMS Text Messages
- Non-Linux FOSS: Code Your Way To Victory!
- October 2015 Issue of Linux Journal: Raspberry Pi