/    Sign up×
Community /Pin to ProfileBookmark

Disadvantages of include?

I have a habit of splitting my contents in separate file and include them in main script. It helps to manage. But,I was wondering is there any disadvantage of using include()? How many files can you include in a script without hampering the server/client side performance?
Thanks in advance.

to post a comment
PHP

20 Comments(s)

Copy linkTweet thisAlerts:
@SrWebDeveloperDec 02.2009 — There is no magic answer for this that works for everyone because it depends not just on the code but also the server architecture including memory, disk space, caching ability and so on.

I suggest you run simple benchmarks on your code and determine if performance is being affected by too many includes or requires. One way is to start a simple script timer at the top of your code and end it at the bottom and output the script execution time in microseconds as demonstrated here in this nice how-to. There are also commercial packages such as Zend Optimizer, Zend Studio's Profile, Apache Benchmark tool and Pear has a benchmark package as well.

But in terms of "include", specifically, here are general tips to optimization:


[LIST]
  • [*]Include is more expensive than include_once

  • [*]Use syntax: include '/path/to/file.php'; // single quotes, no parenthesis so PHP doesn't have to parse for variables if you don't need any

  • [/LIST]

    Caching:

    Using include is less expensive for content retrieval than database queries, generally, but for templates and theming you can optimize them by utilizing [B]caching[/B], which actually uses both methods in many apps I've seen. Run benchmarks on a properly cached template based site vs. one that isn't and you'll be impressed, trust me. For caching techniques check out this excellent tutorial to create a template/theme caching class. Enjoy, and cheers.

    -jim
    Copy linkTweet thisAlerts:
    @NogDogDec 02.2009 — 
    [LIST]
  • [*]Include is more expensive than include_once

  • [/LIST]

    [/QUOTE]


    I have never tested it, but have read in a number of forum posts here and elsewhere that include/require_once has more overhead processing than include/require, since the *_once() functions have to do additional processing to check to see if the requested file has already been included. Of course, we're likely talking very small differences in actual time either way, and for me it's all hearsay at this point. Anyone have any definitive evidence on this? (Not that I'm really worried, just curious.)
    Copy linkTweet thisAlerts:
    @SrWebDeveloperDec 02.2009 — I looked at what I wrote about includes being more expensive than include_once, and I think I got that b-b-backwards! Oops.

    Yeah, the differences are small when compared head to head. In a large template based system, for example, it might have a serious impact over time on a heavy load server. For most sites, it likely won't be an issue.

    My comments on the caching mechanisms really is the key to optimizing performance when includes are used more than sparingly, i.e. a template driven site where all pages require numerous includes (header, footer, content areas, nav bar, and so on.... i.e. *.tpl files)

    -jim
    Copy linkTweet thisAlerts:
    @MindzaiDec 02.2009 — I just ran a quick test as I was interested in quantifying this a bit.

    I made 10000 copies of a HTML file and included them all with the following script:

    [code=php]
    <?php

    $start = microtime(true);
    for ($i=0; $i<10000; $i++) {
    ob_start();
    include "/var/www/test/files/foo$i.htm";
    ob_end_clean();
    }
    $end = microtime(true);

    $time = $end - $start;
    print "included $i files in {$time}s";

    ?>
    [/code]


    foo{0-9999}.htm are ~50KiB.

    I ran the script with include, include_once, require and require_once 5 times each and took an average of the results:

    [B]include[/B]: 10.099652s

    [B]include_once[/B]: 10.303111s

    [B]require[/B]: 10.257192s

    [B]require_once[/B]: 10.240087s

    So as far as I can tell that are all pretty similar, being around 0.001 seconds per file. Obviously this would probably increase using PHP files, but it doesn't seem too intensive and probably not worth worrying about for a reasonable number of includes.

    I'm using PHP5.2 btw, don't know if these results would apply to older versions.
    Copy linkTweet thisAlerts:
    @svidgenDec 02.2009 — My assumption is that the combined indexing overhead of performing [I]hundreds[/I] of [B]include_once()[/B]s will still be far less than accidentally [B]include()[/B]ing a single file twice unnecessarily--even with caching.

    In any case, I've seen fully functional sites running with [B]include()[/B]s ranging into the 30's, 40's and quite possibly higher [COLOR="Gray"](many implicit [B]include()[/B]s)[/COLOR] with no ... [I]significant[/I] performance issues. Though, my personal thought is that there is [I]generally[/I] no [B]need[/B] for more than [I]about[/I] 10 ... [I]maybe[/I] a few more.
    Copy linkTweet thisAlerts:
    @svidgenDec 02.2009 — I ran the script with include, include_once, require and require_once 5 times each and took an average of the results:

    include: 10.099652s

    include_once: 10.303111s

    require: 10.257192s

    require_once: 10.240087s[/QUOTE]

    Wish I'd seen this before I posted.

    Anyway ... Did you do a pre-run to fill the OS cache? And do you have any other form of caching installed?
    Copy linkTweet thisAlerts:
    @MindzaiDec 02.2009 — Anyway ... Did you do a pre-run to fill the OS cache? And do you have any other form of caching installed?[/QUOTE]

    No other caching.

    I wouldn't have thought the OS file cache would have much effect, at least not much effect that wouldn't benefit each of the 4 functions equally. However by way of experiment I repeated the test with the following code, which deletes and re-creates files before each include:

    [code=php]
    $path = '/var/www/test';

    if (sizeof(glob("$path/files/*")) > 0) {
    for ($i=0; $i<10000; $i++) {
    unlink("$path/files/foo$i.htm");
    }
    }

    $start = microtime(true);
    for ($i=0; $i<10000; $i++) {
    copy("$path/foo.htm", "$path/files/foo$i.htm");
    ob_start();
    require_once "$path/files/foo$i.htm";
    ob_end_clean();
    }
    $end = microtime(true);

    $time = $end - $start;
    print "included $i files in {$time}s";
    [/code]


    [B]include[/B]: 13.984048

    [B]include_once[/B]: 14.384155

    [B]require[/B]: 13.511622

    [B]require_once[/B]: 14.449052

    Obviously this has an effect on the overall time, but I still don't see a significant difference. Maybe I'm missing something, but I find these results a bit surprising. Maybe 5.2 has been optimized enough for this not to be an issue? I know they did a lot in terms of optimizing.
    Copy linkTweet thisAlerts:
    @SrWebDeveloperDec 02.2009 — Thanks for posting the benchmarks, Mindzai. Interesting results and excellent analysis.
    Copy linkTweet thisAlerts:
    @svidgenDec 02.2009 — I wouldn't have thought the OS file cache would have much effect[/QUOTE]
    Yep. The OS keeps a cache of all "recently" opened files--kicks out the "oldest" file(s) from the cache when new files are opened. You also need to consider the disk cache--that's two levels of caching you need to consider when benchmarking. For an inactive disk, the difference between reading a [I]small[/I] cached file and an uncached file can be orders of magnitude--1ms versus 10ms--multiples of this for an active disk.

    Your benchmarks show access times around 1ms--indicating they're probably being read from a cache somewhere (most disk [I]seek[/I] times are between 5ms and 10ms).

    For the purposes of this benchmark, I think it would be most reasonable to "force" all of the files into the cache--I think we want to capture the cost of the [B]include()[/B]s independently of disk access, since they probably [B]will[/B] be cached during a live web request.
    Copy linkTweet thisAlerts:
    @MindzaiDec 02.2009 — Yes, but surely that would apply equally to all of the functions. It would opnly make a difference if it was enabled for some tests and not others I'd have though? I thought what we are interested in here is the differences between include, include_once, require and require_once? Surely caching or not, the same conditions exist for all of them. I was under the impression any difference would come from PHP's processing, for example examining symbol tables etc for the *_once family.
    Copy linkTweet thisAlerts:
    @svidgenDec 02.2009 — Yes, but surely that would apply equally to all of the functions. It would opnly make a difference if it was enabled for some tests and not others I'd have though? I thought what we are interested in here is the differences between include, include_once, require and require_once? Surely caching or not, the same conditions exist for all of them. I was under the impression any difference would come from PHP's processing, for example examining symbol tables etc for the *_once family.[/QUOTE]

    Well, not necessarily. With a [I]true[/I] disk access potentially costing 10 to 100 times that of a cache hit, even a single cache-miss can severely taint your results. You need to ensure that they are either [B]all[/B] cache-hits or [B]all[/B] cache-misses. Given the intention of the benchmark, it's more sensible to ensure that they are all cache-[I]misses[/I] somehow.

    Although, seeing the results as they are, I think we can safely assume that you don't have to worry about a "lot" of [B]include()[/B]s for most applications. Just be aware, that if you accidentally perform an [B]include()[/B] multiple times on file(s) with significant payload, you're paying a lot more for the additional [B]include()[/B]s than you would for the additional [B]include_once()[/B]s.
    Copy linkTweet thisAlerts:
    @MindzaiDec 02.2009 — Yes I see your point svidgen. It's pretty safe to assume the files in benchmark 1 were all subject to os cache - the machine it was run on has about 4-5GiB RAM in use as cache most of the time with plenty to spare should the OS need more. The HDDs on-board cache I guess is around 32MiB, but like you say I can't say one way or the other if every file is in it or not though.

    The second benchmark should overcome this though as the files only exist right before they are included so they can't be cached.
    Copy linkTweet thisAlerts:
    @NogDogDec 02.2009 — Generally the issue of doing multiple include/require when you don't need to [b]and without getting a fatal error[/b] are in rather limited circumstances, such as a file that simply sets some application variables. If it defines functions or classes, then you're going to get a fatal error if you try to include/require it a second time, but if all it does is some sort of in-line processing, then you probably actually [i]want[/i] to include it at each point.

    Anyway, thanks to Mindzai for doing those tests; and I'm going to continue to not worry about any performance difference and just use the one that makes logical sense for my application. ?
    Copy linkTweet thisAlerts:
    @MindzaiDec 02.2009 — Yeah that's my conclusion too. I think if you ever have to worry about performance caused by includes you've probably got bigger problems with your architecture anyway.
    Copy linkTweet thisAlerts:
    @svidgenDec 02.2009 — Well, I think the design for includes is--and should--be with the idea that they [I]generally[/I] do not directly perform any operations--but reveal functionality. That is, they ought to define functions, classes, and possibly variables. So, you wouldn't want PHP to re-include these things. But, you would also want to avoid including unused functionality--which warrants conditional includes and the possibility that a particular include is called multiple times.

    IMHO, every include should be [B]include_[I]once[/I]()[/B]-able.
    Copy linkTweet thisAlerts:
    @NogDogDec 02.2009 — Well, I think the design for includes is--and should--be with the idea that they [I]generally[/I] do not directly perform any operations--but reveal functionality. That is, they ought to define functions, classes, and possibly variables. So, you wouldn't want PHP to re-include these things. But, you would also want to avoid including unused functionality--which warrants conditional includes and the possibility that a particular include is called multiple times.

    IMHO, every include should be [B]include_[I]once[/I]()[/B]-able.[/QUOTE]




    I certainly tend to follow that paradigm; but as discussed in another thread recently, just as the Perl folk like to say, "TMTOWTDI": there's more than one way to do it. ?



    (One of those other ways in an OO context is to use an [url=http://charles-reace.com/autoload]autoload[/url] function and avoid a lot of require_once() calls.)
    Copy linkTweet thisAlerts:
    @svidgenDec 02.2009 — Of course, autoloading generally just a conditional [B]require_once()[/B] anyway ...

    ... did we answer the initial question here?
    Copy linkTweet thisAlerts:
    @NogDogDec 03.2009 — Of course, autoloading generally just a conditional [B]require_once()[/B] anyway ...

    ... did we answer the initial question here?[/QUOTE]


    What question? ?
    Copy linkTweet thisAlerts:
    @DasherDec 03.2009 — A web site I built and maintain has about 25 includes, requires, and include_once's. It works great, some of the include access content via MySQL for different areas of the website. Others are just modules. They are done as includes to keep the main index file fairly compact. I haven't done any real timings on it but it loads as fast as most any other website commercial or otherwise.
    Copy linkTweet thisAlerts:
    @svidgenDec 08.2009 — I haven't done any real timings on it but it loads as fast as most any other website commercial or otherwise.[/QUOTE]
    The big question for any site is the number of pages/second it can serve--particularly in parallel. If your page takes 1/10 second to generate, that doesn't necessarily cap you at 10 pages/second. You could easily get 80 pages/second or more on such a page with good caching [COLOR="DimGray"](which may require limiting [B]include()[/B]s)[/COLOR] and concurrency-compatible code.
    ×

    Success!

    Help @ferdousx spread the word by sharing this article on Twitter...

    Tweet This
    Sign in
    Forgot password?
    Sign in with TwitchSign in with GithubCreate Account
    about: ({
    version: 0.1.9 BETA 3.29,
    whats_new: community page,
    up_next: more Davinci•003 tasks,
    coming_soon: events calendar,
    social: @webDeveloperHQ
    });

    legal: ({
    terms: of use,
    privacy: policy
    });
    changelog: (
    version: 0.1.9,
    notes: added community page

    version: 0.1.8,
    notes: added Davinci•003

    version: 0.1.7,
    notes: upvote answers to bounties

    version: 0.1.6,
    notes: article editor refresh
    )...
    recent_tips: (
    tipper: @darkwebsites540,
    tipped: article
    amount: 10 SATS,

    tipper: @Samric24,
    tipped: article
    amount: 1000 SATS,

    tipper: Anonymous,
    tipped: article
    amount: 10 SATS,
    )...