PHP Performance Profiling

Techniques for learning where the bottlenecks are in your PHP-based Web application.
pprofp Options

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:

Sort 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)

Display Options

-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.

Function Call Tree

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:

require_once (2x)
  require_once (3x)
    require_once (2x)
            ... 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 Function Reference

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.



Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.


Valeriu Palos's picture

Great article! APD is a great way to have a local and accurate profiling of your code. That is very useful in large applications since you can concentrate on a specific subsection of the code for optimization without being distracted by other stuff.

However, many times I find that using XDebug+Valgrind is a very good idea, because it can give you a good picture of how your entire application behaves and what are its most expensive (or critical) modules. Also the XDebug method is also the most unobtrusive I think (you only need very minor changes in your code for this to work).

apd not working from within apache server

mukul's picture

HI, I am a newbie in APD, require your help to profile our PHP application. I have installed APD 1.0.1 on a Linux box and I am able to profile sample php scripts by firing them from shell as “php samplescript.php

Re: PHP Performance Profiling

Anonymous's picture

Another nice way to analyze the trace file is by doing
$ pprof2calltree -f [pprof tracefile]
and then open the resulting file with KCachgrind

installation of APD not so easy

misterff's picture

Installation of APD on my Debian system doesn't turn out to be so easy.
I just upgraded to Apache 2.2.0 and PHP5. I tried to install with the pear command, which gave me the following:

$ pear install apd
PHP version >= 5.0.0RC3-dev is required
apd: Dependencies failed

I also tried with:

$ apt-get install php5-apd

But php5-apd doesn't exist so I installed php4-apd which doesn't work.

Any idea's?

RE: installation of APD not so easy

Rene's picture

I had the same problem installing apd on my gentoo machine.
It won't help you, but after the problems I had, I found out the for Gentoo apd is in portage (pecl-apd)
There might be some dependency problems, but once you fix those, apd works.

APD is a pecl package

Stefano Canepa's picture

I found out that to install apd on PHP 5 you need to use pecl install apd command and not pear install apd

apd install errors

Anonymous's picture

has anyone solved this problem yet? tried pecl install apd, but no pecl command available. tried to install pecl, but instructions are too ambiguous -- Does apd REALLY require php v5.0 or is this a bug in the installation software?

After using "pecl install

Anonymous's picture

After using "pecl install apd" and putting where php.ini wanted it there were a few more php.ini directives to add before the module showed up on my phpinfo page. See:

Check the link

jostmart's picture

I managed to install efter looking trough this page: