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

From: Date: Tue, 10 Jul 2007 02:43:04 +0000
Subject: Re: Benchmark results for require vs require_once with and without APC (hard numbers for the allfiles.php debate)
References: 1 2  Groups: php.pear.dev 
Request: Send a blank email to pear-dev+get-47356@lists.php.net to get a copy of this message
On 7/9/07, Adam Ashley <aashley@adamashley.name> wrote:
I get the exact opposite to your benchmarks. my files are exactly the same as those described by you with one major difference, require.php is done in a way closer to the intended behaviour of the coding standards. it has only a single require for the file to be pulled in. The entire point of the changes are to get to the point where every file from PEAR is attempted to be included once and only once. If you need DB for Auth, Config and Auth_PrefManager you place require 'DB/allfiles.php'; require 'Auth/allfiles.php'; require 'Config/allfiles.php'; require 'Auth/PrefManager/allfiles.php'; not the case of require_once 'DB.php'; require_once 'Auth.php'; require_once 'Config.php'; require_once 'Auth/PrefManager.php'; which works out to be, once you follow all the files: require_once 'DB.php'; require_once 'Auth.php'; include_once 'DB.php'; require_once 'Config.php'; include_once 'DB.php'; require_once 'Auth/PrefManager.php'; include_once 'DB.php'; Now just sit back and think for a minute which one might be faster? And for completeness my numbers on your tests: ./requireonce.ab
   Requests per second:    1130.07 [#/sec] (mean)
./require.ab
   Requests per second:    1214.26 [#/sec] (mean)
./requireonce.ab.apc
   Requests per second:    1478.17 [#/sec] (mean)
./require.ab.apc
   Requests per second:    1669.79 [#/sec] (mean)
Obviously a different box to yours but all I've done for the tests is restart apache between each run and install apc using pecl install apc. I've never used APC before (at least not successfully), I prefer xcache. Adam Ashley 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
Perhaps you should both send your PHP versions, Apache versions, Distribution, CPU, memory... -- Justin Patrin

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