I have a colleague who is looking into opcode caching/Zend Acceleration (I've always assumed these are the same thing) for our PHP based application. His Benchmarks appear to indicate that we're NOT seeing a performance benefit if we include our (large) class libraries with require_once, but we DO see the performance benefit when using include_once.
This smells fishy to both of us, but I don't have time to check into our benchmark methodology myself and my colleague has more tolerance for the smell of fish than I do. :)
Has anyone ever run into anything like this? If not, any thoughts on other things that might be causing the appearance of a performance increase by switching from include_once to require_once?
For starters, both calls (require_once and include_once) double-check if a file has not been included before.
So the way they both achieve this is by searching the file in all available paths and by essentially checking if it hasn't been in the mix before etc..
In the background what happens is that they evaluate all the different options (e.g. multiple include_path's, etc.) and then by creating the realpath from this abreviated form they create a unique identifier. There is only one and the same path - not two.
This is already not the fastest process on the planet and generally happens on each request with PHP. Then add another expensive operation which is the stat when it creates what I called the realpath (realpath, because it's sort of what realpath() does) to check if the file exists.
Correct me if I am wrong, but APC has optimizations especially for this case.
So anyway - now on to the difference between require_once and include_once, which is that require_once evaluates the file (for low-level parse errors, etc.) when it includes it. This is an additional check which you can get rid of if you have enough QA in place that a parse error can never sneak into an include.
It's just tricky to find otherwise. :-)
(Something to consider: You could develop with require_once and replace all calls with include_once when you deploy.)
As for an opcode cache - I'd recommend APC. It's been discussed on stackoverflow before. Personally, I am/we are using it for a while (we handle roughly 100k visitors/day with 3 frontends and 1 backend) and we are very happy. APC is also optimized for the require_once/include_once madness.
A pretty cool side-effect is that APC also allows you to store PHP variables in memory - sort of persistant, etc..
A couple additional pointers:
A lot of people claim to speed up any application with __autoload.
With an opcode cache, avoid conditional require_once/include_once (e.g. in loops or in control-flow).
Some people say that /absolute/path/to/file.php in include_ or require_once is faster than relying on the include_path.
The order of the paths in your include_path matters as well.
Hope that helps.
I can't guarantuee anything as i haven't looked deeply enough into it, but yes, i have seen speed differences between the two. They were never significant enough to me to move to include_once instead of require_once though.
I always assumed the difference was because require_once has to do more work underwater. at least one more potential error to prepare for and handle, and a lot more to do when the file required does not exist.
Related
I just started using xdebug to profile my application and immediately noticed something strange in the results. One of the require_once functions is shown to be taking around 12% of the processing time. There are quite a few other calls to require_once throughout the application and they're all taking less than 1% of the processing time.
The poorly-performing require_once is including a file that's not significantly different or larger than any of the other files, so I'm not sure what could be causing the problem. Has anybody else ever experienced something like this?
Edit: Wanted to provide a little more info. I'm doing the profiling on windows using XAMPP. Normally the application runs on a unix box. I haven't got an easy way to get xdebug onto the box, so it may not be feasible for me to try and compare the results that way.
One last edit: Here's an idea of the code in case that helps (intentionally being vague for the standard CYA legal reasons blah blah blah):
This class is the one with the slow include (test.inc):
require_once('/xx/yy/zz/dao/basedao.inc');
require_once('/xx/yy/zz/vo/test.inc');
class TestDAO extends BaseDAO {
// bunch of code to handle database records and return VO objects
And this is the file being included:
require_once('/xx/yy/zz/vo/basevo.inc');
class Test extends BaseVO {
// bunch of properties, getters/setters, that kinda stuff
I have quite a few other VO/DAO objects that are built the exact same way, without any issue. All are located within the same respective paths.
That does indeed sound odd. Definitely worth pursuing, though it'll be hard to work it out for sure without seeing the actual code. 12% of the total program time for a single require_once() does sound very excessive.
But here are some thoughts on possible avenues of investigation:
require_once() keeps a lookup table of files that have been included, so perhaps it's slowing things down having to refer to that lookup table.
If this is the cause, you could solve it by using require() rather than require_once() wherever possible.
Perhaps it's the path lookup? Are you including a path with the filename? If not, it'll be checking in a number of places to find the file; perhaps it isn't in the first place it looks, it'll be taking longer to find the file before it can include it.
If this is the cause, you could solve it by being more specific about the path in your code.
Hope that helps. Would be interested to hear how this pans out.
Oh, and by the way -- if your biggest problem area in your code is require_once(), then it sounds like you've done a good job with your code! I dream of the day require_once() even shows up in my profiler reports, let alone with an significant effect.
I'm creating a theme for my client and they are really picky on the page load time.
So I've thought that the less code will help the page load faster, and I come across the php code to include once.
<?php
include_once "a.php"; // this will include a.php
?>
and if I do with the if statement to include once I have to declare a variable and change the variable to false after the second check
What will be the most efficient coding and help page performance?
I also want to know if there is even better way of coding to help to make the page load faster when we want to execute the code from a file.
Thanks
It might have been true in the dim and distant past that include_once was a lot slower than include, but that was the dim and distant past. PHP's include_once functionality has been optimized heavily since then. Unfortunately, there's still lots of old articles floating around on the internet that make the claim that include_once is slow, even though it's no longer true.
Even if include_once was a lot slower than include, the odds are it wouldn't cause an appreciable performance impact unless you were including thousands and thousands of files. Investing time on speeding it up is a micro-optimization, especially if you have no evidence that it's a bottleneck in your code.
First and foremost in any project is getting the code to work to specifications. Code that's slow but works is still better than code that's fast but doesn't work. Once you've got the code working and passing all its unit tests (you are using unit tests, right?) then you can start worrying about performance. And when you get to that point the first thing you should do is profile your code to discover where the actual bottlenecks are, not start guessing at where you think they might be.
In my opinion PHP doesn't affect the file executing time very much. Unless you are looping trough 1000 loops or results I think you can't really speed up the file executing time. So I suggest you to don't worry about these things.
I should use the include_once/require_once because it is a PHP build-in function, simple to use and exactly what you need.
Based on what is suggested here and there. require_once is the fastest. There is also __autoload, but with some performance draw backs. As it is suggested here it matters if you use relative or absolute addressing too.
Think of PHP templating.
I was recently contemplating whether it makes sense to read a template file once, storing it in memory, and then parsing it (replace placeholders with values, e.g.) rather than require-ing that file as many times as you need it. A usage scenario would be a list with list items templated as separate files. The first thoughts I had were inclined towards the former solution, because I reckon replacing values would be an easier operation than requiring the file from the file system. Later, however, I realized that pretty much all hard disk drives (or other storage, for that matter) have their own caching, and requiring the same file over and over, will not result in it being re-read each time, but rather re-served from the cache.
Any thoughts are appreciated.
I assume by "disk cache" you're actually referring to the page cache? Wikipedia: Page Cache
If so I wouldn't really be inclined to trust something like this with the performance of my application. Don't forget the page cache only uses UNUSED memory and will happily spit it back out when needed.
I would be inclined to use something like APC as an object cache, this has the great side effect of not having to actually rewrite any of your code as it's all done behind the scenes. Another possibility would be to just assign your template to a variable and constantly reuse that. Or, if you wanted to you could even use Memcache, this kind of stuff is more useful for caching database returns though, or large datasets.
Sorry for the slightly incoherent ramblings...
I was recently contemplating
That's quite wrong of you.
Groundless contemplating out of nowhere seldom does any good but most likely will put you in a trouble. Just out of nowhere.
Instead of contemplating, one have to do profiling.
Of course no to measure any changes, like H Hatfeld said, but to determine, if they need any changes at all. Most of time it turns out that you were barking wrong tree.
Profiling is the right thing to make you bark the right one.
whether it makes sense to read a template file onc, estoring it in memory, and then parsing it
For the highload(or bloated) projects it makes.
So, PHP already have such a feature, called bytecode cache. There is a plenty of the thing on the market, at our company we are using eAccelerator.
But most of time default every-request parsing is enough.
You are absolutely right about filesystem cache and parsing being blazingly fast, much faster than usual application logic, which has to be optimized at the first place.
Every time you include a file, PHP has to parse it. This penalty can be offset using an opcode cache like APC. If your templates don't contain any PHP (which it sounds like they don't), I would recommend loading the template into memory once and then re-using it as needed.
Another thing to keep in mind when looking to optimize your code is make sure you can measure the change. Use something like Xdebug to profile your code and measure what effect your changes are having.
Edit
Since the files do currently contain PHP, take a look at this question/answer. I would recommend putting a function in the file so that it only needs to be loaded once, but can be called multiple times with different parameters.
Do you position all of your include_once and require_once at the start of the file, so it's clear what it's dependencies are, or do you put them at the most local scope where they are used, for efficiency?
Let's say I have an error handling file which has a function to display an error message - would you ...
require_once('error_handling.php');
... lots of code ...
if ($should_be_true === False)
{
ReportErrror(); // declared in error_handling.php
}
or do you
... lots of code ...
if ($should_be_true === False)
{
require_once('error_handling.php');
ReportErrror(); // declared in error_handling.php
}
hmm, looks like they deleted the best-practise tag, along with subjective in the great tag purge of '10
This is probably a matter of taste for the most part.
In C/C++ style, I always put them on top, so - as you mentioned - the dependencies are immediately clear. Also, it gives you the option to rearrange the order of inclusion (which should normally never matter).
Now, since this is a runtime affair (unlike C/C++), it would make sense to postpone including huge files that are rarely ever needed.
It's a matter of balance - cleaner code (IMHO) vs performance. I would tend towards cleaner code, unless you have a PHP file that is a) called a lot, b) uses a huge PHP file that is c) almost never needed.
I'd most definitely go with the second example, because to load in stuff that potentially wouldn't be used is just evil.
Meh. Totally dependent on the situation.
If it's a small include and you're going to use it in 95% of situations, top is fine. Top really is fine for almost all cases.
But if it's an absolutely huge library to, say, parse something that will only come up in 5% of requests, require when needed. It might be worth making a comment at the top to make the dependency known, however—happy medium?
Anyway. It's a judgment call every time. Best not worry too much about the performance issue for the uncertain cases until milliseconds of performance actually become an issue for you. (And wouldn't that sort of popularity be an excellent issue to have?)
Assuming PHP version >= 5.2, which is a better solution for managing includes:
require_once DEFPATH . 'config.inc.php';
or
if (!defined('FOOBAR')) require DEFPATH . 'config.inc.php';
or something entirely different?
Site does not use a front controller or autoloader. Typical number of files needed to be included is 3 - 8.
I've heard, here and elsewhere, that require_once adds overhead and does not play nice with caching. But I've also heard that a small number of require_once statements is OK in practice in later versions of PHP.
There must also be some overhead associated with checking if something is defined, but that may be less of an issue.
In general, which is the better practice and why?
Yes, require_once() comes with CPU and memory overhead, but not in any way significant to performance. In fact, it's a very efficient operation because PHP just does one hashtable lookup to decide whether that file has already been parsed or not. Don't give yourself any unnecessary headaches with hacks like your !defined('FOOBAR') example, because it does the same thing only with less elegance.
What takes time during a PHP request is the file path lookup and then the subsequent parsing step. The amount of resources needed for the runtime to determine whether you've already parsed the file before is negligible.
There are a few things you can do to make your request run faster:
avoid unecessarily long search path in include() and require()
use absolute include paths were possible
include stuff only as needed
cache large output fragments
cache complex query results
write terse code, offload seldom-used functionality to included-on-demand source files
If you're using a code cache or some kind of runtime optimizer, read the manual - they have different strategies that can actually hurt performance or introduce bugs depending on your code.
One final advice: beware premature optimization! Requests taking between 0 and 50 miliseconds on the server are practically not distinguishable on the user side.
I would use require_once in your case. Even if it adds overhead, you can neglect it, especially when you only have to include max 8 files. The require_once is a lot less error prone and more 'clean'...
In your example, checking if FOOBAR is defined would be better. But that's because your example is not specifying a full path to the include file.
You should always specify the full path for just about anything, unless you specifically want to use a relative path. Otherwise PHP needs to search in the various search path directories for your file. If it happens to be in the last search path directory, that's a bit of overhead.
I always create an array containing the full path to directories I load files from, then I prepend the appropriate path to the file I'm loading.