16 ms·
PHP "require" Performance
- veb 15y agoThere's a really nice discussion on Stack Overflow about this: http://stackoverflow.com/questions/186338/why-is-require-once-so-bad-to-use http://stackoverflow.com/questions/186338/why-is-require-onc...
- bkrausz 15y agoThe require vs. require_once was a byproduct of this research: I was really interested in __autoload vs. require, as that seems to have fewer numbers online for it.
- mkjones 15y agoOne way to improve cpu-bound performance is to switch to something like HipHop for PHP [1], which compiles PHP down to C++ and runs that. Granted, this incurs a non-trivial switching cost. However, it's scary to me that someone is suggesting the potentially fatal-inducing use of "require" over "require_once" (if you call it twice on the same file, you end up re-defining whatever classes or methods were required and the script dies). It seems like optimizing for developer time and simplicity over cpu utilization is better here. Using HipHop would incur a one-time operational cost, but I suspect it would be worth the additional developer and speed gains. [1]: https://github.com/facebook/hiphop-php/wiki/ https://github.com/facebook/hiphop-php/wiki/
- jonhohle 15y agoBy using __autoload and a class/file naming convention, you can get away with using just require, and not having to write require statements manually. Decreased time for developers, and near optimal load times.
- KevBurnsJr 15y agoHPHP is realistically only going to get you like 5% performance bump. Performance Talk by Rasmus Lerdorf http://vimeo.com/12416792 http://vimeo.com/12416792 (skip to 14:30)
- wvenable 15y agoThere should really be no reason why __autoload() should be significantly slower than require_once(). It's even trivially easy to ensure your classes are __autoloaded()'d from absolute paths to make opcode caches happy.
- forgotusername 15y agoMy initial thought was "surely it's just a quick hash lookup", but then require_once is probably using the canonical path for that lookup, which involves calling realpath() or abspath(), at that point all bets are probably off, especially in a shared hosting environments involving things like NFS. Edit: I looked at the implementation. require_once/include_once unconditionally opens the file, whether it has been loaded already or not. Attempting to follow that path through about 10 levels of indirection (seriously), at some point the PHP implementation passes its notion of the path back to Zend, which suggests possible abspath() etc. Also somewhere in PHP's streams.c I see it unconditionally seek()ing the new file too. If nothing else, then the layers of crap I just trawled through might cause some slowness, if not some heavy library call like abspath(). I just remembered why I stopped using PHP. :)
- spudlyo 15y agoUgh, you're bringing up bad memories for me. I was once bit badly by the require_once/realpath() problem. require_once("/foo/bar/baz/random/crap/foo.php"); The above requires 5 lstat(2) system calls thanks to realpath() and a typical WordPress-MU page load for us was calling lstat over 5k times. Over NFS that's 5k round trips to the server for every page load. Thankfully there is a knob you can tune in PHP 5.1.x (realpath_cache_size) that caches all those lstats, but as usual, the default is (16K) is too small to be of any use.
- danielrhodes 15y agoEven if autoload is slower, it's such a simple concept that even if you use it early on and need to take it out later, you wouldn't have to restructure anything. If you know performance is that big of a deal upfront, anything bug vanilla PHP might not be the best choice since the interpreter will probably become a bottleneck.
- ck2 15y agoHmm, PHP 5.2+ is still that slow with require_once ? I thought they fixed that. Anyway, just use function_exists instead.
- bkrausz 15y agoYup, we're on 5.3. May have something to do with the relative vs. absolute paths (we use relative), but still... Turns out we didn't need require_once anyway, all but a couple of includes in our entire codebase were in that one area.
- nbpoole 15y agoOut of curiosity, what does your include_path look like? Is ./ the first element, the last, or somewhere in the middle?
- bkrausz 15y ago. is the first entry
- wvenable 15y agoAs quickly as possible I turn relative paths to absolute paths (with __DIR__) to avoid any more overhead there. I also empty the include path; no need to have PHP searching for files all over the place.
- KevBurnsJr 15y agoAsked author to include APC enabled/disabled as a variable in comparison. Edit: APC was enabled
- rexreed 15y agoI'm trying to understand the metrics here. Doesn't the first test show that _autoload is actually much faster than require or require_once? require_once: 1579 require: 1318 __autoload: 578 The second test shows a similar result: require_once: 1689 require: 1382 __autoload: 658 Am I missing something here?
- bkrausz 15y agoYes, __autoload is much faster, because it only ends up loading ~5 of the files. Previously we had included 30 files by default, and even though __autoload is slower on a file-by-file basis, the savings on the files we didn't need to load at all made it very worthwhile.
- invisible 15y agoAlways use Autoload if you can for large projects. The DRAMATIC performance losses of requiring files and classes you do not ever use during a page load can be pricey. Rasmus' quote was saying that PHP/APC can't save the opcode for a file WITH all of the includes if there is any conditional associated with the require. This means that each include's opcode will be pulled from cache each time (not a big deal!!!). [2006, http://pooteeweet.org/blog/538/ http://pooteeweet.org/blog/538/] Things in favor of Autoload: 1) Ease-of-use of not worrying about if your class is available 2) If you don't use Autoloading and require clases, you have to load all of those from the opcode cache (and make APC keep track of them) despite that you may not be using many of those classes at all. 3) It helps encourage putting things in classes (whether they are static functions or not). 4) If you ever need to conditionally require a class, you are likely going to run into the same opcode cache hits (instead of NOPs) as Autoload. You'll have to include ALL of your classes to avoid the problem.
- skalpelis 15y agoI'm not sure #3 is really a benefit.
- Sizlak 15y agoEvery time I see an article like this I thank God I'm not using PHP. It's always, "Remember to always use do_something() instead of dosomething() or else something will suck for some reason."
- wvenable 15y agoThis article is a serious micro-optimization and, in general, not something people should be that worried about. If you nit-pick enough, all platforms have these sorts of issues.
- jessedhillon 15y agoIn a good language, include/require[_once] should all be reduced to the same one statement, e.g. Python's import. Don't you think it's a ridiculous notion that the distinctions between include and require (and the once variants) are meaningful enough that programmers should be able to express them?
- evan0202 15y agoPHP using __autoload and namespaces looks and feels exactly like Python using imports. You see, the PHP developers have been actively improving a lot of aspects of the language recently, and the latest release, 5.3, had a ton of really nice improvements and features, such as namespaces. I'm not going to say PHP is the greatest language every invented, and in fact I am a huge fan of Python. But I do not think PHP deserves the "In a good language..." treatment. It is a language that is getting better everyday, with a strong and vibrant development community and massive user adoption. It is a good language.
- ooh456 15y agoamen. nobody chooses to use php on new projects but at least it's easy, fast, and pays the bills.
- 15y ago
- joshfraser 15y agoKeep in mind those numbers are microseconds. If you are looking for ways to improve your performance, there are probably lots of other places to focus your attention that will have a much greater impact. For example, optimizing your frontend will give you far more bang for the buck and in fact I'd argue that sometimes it's worth the extra 300 microseconds for the sanity of your development team.
- ericd 15y agoI don't believe he provided units, since it was over a large number of runs, and the units would be relative and meaningless due to hardware and setup differences (he said as much in the comments, as well).