Re: Benchmark results for require vs require_once with and without APC(hard numbers for the allfiles.php debate)
| From: | Philippe Jausions | Date: | Fri, 13 Jul 2007 18:58:34 +0000 |
| Subject: | Re: Benchmark results for require vs require_once with and without APC(hard numbers for the allfiles.php debate) | ||
| References: | 1 | Groups: | php.pear.dev |
| Request: | Send a blank email to pear-dev+get-47481@lists.php.net to get a copy of this message | ||
Travis Swicegood wrote:
> 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
I ran a set of benchmark tests, using a pretty simple real-life-like
sample application and using multiple parameters: with/without opcode
cache, allfiles, "traditional" require_once, and a PEAR2_Load class loader.
http://pear.11abacus.com/dev/PEAR2_Benchmark/results.html
== Conclusion:
To get the best performance use an opcode cache combined with an
allfiles.php and all *_once removed from the code.
Without an opcode cache, the original PEAR packages fared well, as long
as the class name <-> file name rule is respected. Note how the
"require_once" test changes raking goes from fastest to almost slowest
whether or not that rule is followed on just one package.
-Philippe