Every project, small or big, has some configuration in the form of keys and their associated values, commonly defined using constants. These configuration settings normally get loaded upon each request, making them a good target for optimizations.
The contenders
By default, PHP supports
defines and
class constants, but extensions such as
APC and
hidef can give you a better performance if enabled.
The APC extension has a function to define constants using an array, called
apc_define_constants(). The hidef extension is different, it reads the constants from a set of files during PHP initialization; this makes the constants available at compile time for immediate substitution.
Setup
To test the four aforementioned methods, I've chosen a simple set of operations using the most commonly used types of constants: integers, strings and doubles. The script would then run those operations in a tight loop for a fixed number of iterations and record CPU time and memory consumption. Lastly, the APC extension is not being used as an opcode cache for this test.
The outcome reveal that the define() method yields the longest running time while class constants method yields the higher memory consumption; the results of those methods are therefore used as the benchmarks for the other results.
Performance results
Test performed | Time spent | Memory consumed |
Using define() | 100% | 32.6% |
Using class constants | 30.2% | 100% |
Using apc_define_constants() | 24.2% | 32.0% |
Using hidef | 13.9% | 13.5% (*) |
(*) hidef consumes memory during initialization, but this was not taken into account for this test
Analysis
The clear winner of this test is the hidef extension; upon initialization it creates constants that are both persistent and available during the compilation phase. The results opcode is superior to any of the other methods described above. However, all this goodness comes with a drawback: configuration settings are instance wide, which impacts all setups of PHP that runs beyond a single web request (e.g. Apache module or FastCGI).
Using apc_define_constants() is a good runner up in terms of performance (6% faster than class constants) and memory consumption (comparable to using define). It uses optimized code to create constants, speeding it up threefold. Some people may still use eAccelerator and/or Zend Optimizer, but APC is much more actively developed and has additional features to work with variable caching (like Memcached but only server wide). And it will be integral part in the upcoming PHP6 (or whatever they're going to call it).
In the bottom two we still see a substantial difference in execution time between class constants and using define(). Using class constants has the benefit of being available during execution time, which makes it a prime candidate for further optimization using APC. However, the OO nature of this method has two drawbacks: resolving the constant still needs to take place during run-time and there's more memory consumed (at least three times that of the runner up).
Conclusion
If you're only running one site per web server instance or you can namespace your constants, choose hidef.
If you're already using the APC extension or interested in doing so, choose apc_define_constants().
If you don't mind the extra memory consumption to yield 300% CPU time improvements, choose class constants.