PHP define() terribly slow?
I was profiling one of my favorite large PHP applications today using APD. I kept getting what seemed to be strange results -- it was telling me that bunch of defines statements (30+ of them) were responsible for an inordinately large percentage of the page generation time. On minimal pages it was as much as 37%. Even on the well-known largest of pages, they were still clocking in at a not insignificant 5%.
That just didn't seem possible.
So I wrote a bunch of variants on just straight timings of define('X', y)
versus $X = y
to get some purer comparisons. This was easier said than done.
PHP appears to be smart about setting a variable to the same constant again. Even without that, define()
is doing something a bit different in that it is creating a global symbol in PHP's symbol table, whereas setting a new value in an existing variable only has to do an assignment; the creation of the variable happens the first time.
I tried using unset()
to force new creation of the variable on each pass through my timing loops, but clearly I was distorting the results by the time used by the unset()
calls. But even with that wasted time, variable assignments were about 3 times faster than using define()
.
With some more fiddling with the code, I was able to factor out the unset()
time.
The end result was that setting a variable is nearly 8 times faster than defining a constant.
This was based on 50,000 iterations through a loop defining 30 different constants each pass, versus 50,000 iterations through a loop setting 30 different global variables.
Somehow, this doesn't seem right. If someone can show me where I'm wrong, I'd be glad to see it. Otherwise, I think there's some optimization opportunities out there, both in existing PHP code, and in the C code comprising the PHP runtime.
- chris's blog
- Login to post comments
Comments
I've seen this before, too.
I've seen this before, too. I work with a high-traffic site hosted on a Mac OS X Server box and when I used APD I noticed the same patterns. Arto's Boost module came in real handy to mitigate that. I tried several versions of PHP, both major versions as well as compilations, including compiling my own. Not sure if it's an OS X thing -- that what you're using, by any chance?
Debian Linux
Actually, I was using Debian Etch Linux with PHP 5.2.0-8etch9, Zend Engine v2.2.0, and APD v0.9. I don't think we can blame Mac OS X for this. We've got some RHEL servers, too. Maybe I can try it there.
PHP is not compiled.
PHP is not a compiled language where a pre-processor deals with macro statements. So naturally a define requires a lot of logic from a parser to determine what it is where a variable is clearly specified with $ and the parser doesn't need to waste time figuring out what it is.
Maybe with roadsend defines could be fast... at least the potential is there