Benchmark results for require vs require_once with and without APC (hard numbers for the allfiles.php debate)

From: Date: Mon, 09 Jul 2007 19:31:42 +0000
Subject: Benchmark results for require vs require_once with and without APC (hard numbers for the allfiles.php debate)
Groups: php.pear.dev 
Request: Send a blank email to pear-dev+get-47299@lists.php.net to get a copy of this message
Howdy all... In response to my own request for benchmarks, I threw together a quick and dirty benchmark. In reading through the various linked messages that were posted earlier, it appeared that the issue is the efficiency of require_once vs. require. To determine the baseline speed, I created two files, requireonce.php which contains two require_once calls against the same file, and require.php which contains two require calls, but one is surrounded by an if(!class_exists()) call. The baseline results are: ./requireonce.ab
   Requests per second:    1712.81 [#/sec] (mean)
./require.ab
   Requests per second:    1179.92 [#/sec] (mean)
In an uncached environment, require with the if() is more than 30% slower proving again the old adage that compiled code is faster than parsed code. I downloaded the latest APC from pecl installed it and reran the tests with caching on. ./requireonce.ab.apc
   Requests per second:    1803.97 [#/sec] (mean)
./require.ab.apc
   Requests per second:    1873.63 [#/sec] (mean)
The increase from non-cached to cached is huge for require, but only marginal by comparison for require_once. So I see the question has how to leverage APC when its present, but still have functional code without a 30% hit in performance when its not. The obvious answer for me is to have an allfiles.php type file present for those using opcode caching, but still use require_once throughout the code to continue along the current path where each file is responsible for insuring that everything it needs is present. To test this, I put together a both.php file where the original call is made via require to take advantage of opcode caching, then included a require_once after that which would of course be skipped: ./both.ab.apc
   Requests per second:    1886.59 [#/sec] (mean)
To make sure that the cache wasn't already primed for the both.php test and skewing the results, I re-ran the require.php and then ran the both.php again: ./require.ab.apc2
   Requests per second:    1895.45 [#/sec] (mean)
./both.ab.apc2
   Requests per second:    1964.27 [#/sec] (mean)
From these results, it looks like we should keep the status quo, as it helps in a tremendous way the non-opcode-caching users out there, but would still provide an all files that does things in an opcode cache friendly way. Personally, I would auto generate this file in Pyrus when its generating the package. It already has a list of all of the files, so it can easily create one if it's not already there. -Travis

« previous php.pear.dev (#47299) next »