PHP’s include_once() Is Insanely Expensive

I’ve always heard the include_once() and require_once() functions were computationally expensive in PHP, but I never knew how much. I tested the following out on my i7 2010 MacBook Pro using PHP 5.3.4 as shipped by Apple.

This first test uses include_once() to keep track of how often a file is included:

$includes = Array();
$file = ‘benchmarkinclude’;
for($i=0; $i < 1000000; $i++){

Took: 10.020140171051 sec

This second example uses include() and uses in_array() to keep track of if I loaded the include:

$includes = Array();
$file = ‘benchmarkinclude’;
for($i=0; $i < 1000000; $i++){
    if(!in_array($file, $includes)){
        include($file . ‘.php’);
        $includes[] = $file;

Took: 0.27652382850647 sec

For both, the include had the following computation:

$x = 1 + 1;

Lesson learned: Avoid using _once if you can avoid it.

Update: That means something like this will theoretically be faster:

$rja_includes = Array();
function rja_include_once($file){
    global $rja_includes;
    if(!in_array($file, $rja_includes)){
        $rja_includes[] = $file;

Tags: , ,

13 Responses to “PHP’s include_once() Is Insanely Expensive”

  1. Preed says:

    Makes one wonder how *_once() is actually implemented, since you apparently implemented it in a way that was about 3600% faster…

  2. Robert says:

    @Preed: I’ve been meaning to look it up, just haven’t had the chance. I first suspected (I don’t actually know) it does file_exists(), and perhaps other verification. But that seems unlikely as the distribution of the several times I tested this was pretty tight, I would have expected file IO to create a much larger distribution, or tail off once it’s cached. I saw nothing to that effect.

  3. Jeff Walden says:

    Note that your implementation is potentially quadratic in the number of rja_include_once calls.

  4. Blusky says:

    I agree with you, but your solution isn’t correct because include path may implement multiple path.
    You should use :

    $path = substr($file,0,strrpos(“/”));
    $file_name = substr($file,strrpos(“/”));
    $rja_includes[] = realpath($path).$file_name;

    instead of

    $rja_includes[] = $file;

    And I think that’s why include_once is so slow 🙂

  5. Robert says:

    @Blusky: Not really. include() uses the first path that’s true. This is repeatable. So your key is the same regardless of the path chosen in the backend.

  6. Blusky says:

    No, imagine you have the following hierarchie :

    a.php -> include_once(“b.php”);
    b.php -> include_once(“a/a.php”);
    a/a.php -> include_once(“b.php”);

    Will you include the second b.php ?

  7. Robert says:

    Assuming duplicate file names isn’t a bad practice already… you should always use absolute paths to your includes. It’s much faster. Disk IO is the biggest bottleneck on a server. Anyone who would use this sort of optimization is already doing that (I can’t think of many php open source projects that don’t do that already). Otherwise you’re essentially going through your path dir’s and doing a file_exists(), that means disk latency.

    I don’t think that use-case really exists for those reasons. This is an optimization, not a catch all.

  8. Blusky says:

    You always use file name such as “/var/www/website/dir/file.php” when you use include ?

  9. chitetskoy says:

    the reason why include_once and require_once is slower because it normalizes the path first (so in “/web/dir/mi.php” calling include(“../includes/foo.php”) will process it to “/web/includes/foo.php”).

  10. Terrasque says:

    Correction… PHP include is insanely expensive 😀

    I tried taking your original include_once and just replace include_once with include and then test speed difference.

    $ time php incNormal.php

    real 0m29.794s
    user 0m13.477s
    sys 0m15.541s

    $ time php incOnce.php

    real 0m2.569s
    user 0m1.216s
    sys 0m1.336s

    Also, as others have pointed out, your code is not functionally the same as include_once.

  11. Dilly Smith says:

    This article is inaccurate and dangerous for developers to stumble upon. Please update it. As Terrasque pointed out, include_once is actually MUCH faster than include. For another reference, see Unless you specifically want to include a file multiple times, you should never use include.

  12. Kamal Khan says:

    The author has claimed it totally wrong here.
    This test has nothing to do with the time cost of include or include_once.

    In the test code, you are checking if the files was included or not when testing for include but for include_once, you are not.

    Hence, for the include_once, it is executing the statement 1000000 times, while for the include, it is executing the statement only once.

    The test does not prove anything as they differ by the fact that it is executed.

  13. mohs says:

    your benchmark comparision is not practical, as the $includes array always only contains one item. It will make a difference if this array get’s larger and the strings in it possibly longer (with subpaths and such).

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

By submitting a comment here you grant this site a perpetual license to reproduce your words and name/web site in attribution.