PHP Xdebug Profiling, pretty graphs!
Tuesday, October 3rd, 2006So today I did some legitimate profiling of some PHP code using Xdebug for the first time. I used KCacheGrind to open the output files. I had a page in our mailing application that allows importing of emails from a csv file or an excel file, which was taking too long and eventually timing out when given a few thousand entries. I was able to profile a few times and improve code until it finally didn’t time out. The first thing was the importer class which implements the Iterator interface (from SPL), in which array_keys was called over and over again in the iterator functions, so had to store that in an instance variable and therefore much improved that area. Next up was the code responsible for putting the emails in the database, profiling showed that it was calling a settings class a lot, about 58% of the time it’s doing MasterSettings::find() call:
That’s obviously not good, easily fixed again with storing it in an instance variable so I have the limit setting I was asking for available instead of querying the settings system every time. Next profiling run showed addSubscriber and getSubscriber to be the two most time consuming operations, and what they were doing that was time consuming:
So the MSList addSubscriber function was calling subscriberCount() on itself a lot, and that was eating a lot of time. Turns out that was querying the database doing a COUNT() every single call, this being done nearly 6000 times in this particular case. Since ’subscribers’ are added and removed via functions, I changed the subscriberCount() function to only pull from database once and then from there, the add/remove functions increment/decrement respectively. That helped a lot but left the getSubscriber() function that calls to the database to see if one exists, otherwise creating an entry. This I tried to improve but realized not much can be done beyond usage of memcached in the database class. I basically cached the database results into a static class variable, which only served to improve performance when importing a list that has a lot of duplicates. This might be an excellent test case for trying memcached out.
After all that, I’m left with the main script file and getSubscriber() taking the most time up, and the script no longer times out, still some concerns about the database hit but the script is a lot quicker now, and Xdebug + KCacheGrind proved to be very valuable.
I highly recomend Xdebug on the awesome stack traces for notices/errors/warnings alone, I don’t know how many times that’s helped when getting a NOTICE from who knows where.
Technorati Tags: php, profiling, programming

