Previously, our code had a section at start of every page:
require_once('include/Foo.php');
require_once('include/Bar.php');
.
.
.
require_once('include/Baz.php');
Each file was a single class of the same name as the file. While we’re well aware of PHP’s ability to Autoload class files, we chose to list each file out is because of a talk by Rasmus Lerdorf. Rasmus discussed file loading performance. In it he mentioned that __autoload
causes issues with opcode caching, and as a result will cause a drop in performance.Speaking of, if you haven’t heard of opcode caching for PHP, stop now and go read up. As simple
sudo apt-get install php-apc
will give you an order-of-magnitude speedup on your website. There’s no reason for any production server to not be using it.Anyway, this may have been true when we only had a includes, but now we have 30 files that we were including on every page load! It was time for some performance testing.
It’s also a fairly well-known fact that
require_once
is much slower than require
…I wasn’t thinking when I used require_once
. I also tested the difference between those two calls.I tested 2 pages. First was our homepage, which only requires 3 of these 30 files. Second was an inner page that requires 5. They were tested with
ab
, and the numbers listed are the mean response times under high concurrency. Lower is faster.For reference the autoload code used is:
function __autoload($name) {
require('include/' . $name . '.php');
}
Results
Homepage (3 required files)require_once: 1579
require: 1318
__autoload: 578
Inner page (5 required files)require_once: 1689
require: 1382
__autoload: 658
Wow! Over a 2x speedup…that’s pretty nice. This led me to wonder: what’s the difference in time when we’re only loading the files we need:only autoload: 618
5 requires + autoload: 530
only 5 requires: 532
Actually having autoload called adds significant overhead to the page, but as would be expected just having it enabled but never invoked doesn’t add any overhead.Conclusion
The main takeaway: if your primary concern is performance, then any file included on all of your pages should be included with arequire
. Any file that’s included on fewer pages can be loaded through __autoload
, especially if it’s only on a few pages. Also, always use APC and never use require_once
unless you absolutely have to.Also, your situation may be different than the situations you see in performance tests, so always run your own metrics.
ab
is your friend.REFERENCES
http://www.gazehawk.com/blog/php-require-performance/
http://stackoverflow.com/questions/186338/why-is-require-once-so-bad-to-use