clarification on the performance of require_once and APC

From: Date: Sat, 25 Aug 2007 18:32:51 +0000
Subject: clarification on the performance of require_once and APC
Groups: php.pear.dev 
Request: Send a blank email to pear-dev+get-47835@lists.php.net to get a copy of this message
Hi, I just tracked down Rasmus on IRC and asked him lots of questions about require_once and APC performance. I think that all of the questions raised in June with reference to require_once were addressed. Here are the facts: * Gopal's fix to include_once in APC 3.0.14 *does* improve the performance of relative include_once when compared to absolute include_once (http://t3.dotgnu.info/blog/php/include_once-mostly-harmless.html) * Gopal's fix to include_once in APC 3.0.14 does *NOT* improve the performance of include relative to include_once - include_once even with apc_stat=0 is still slower than include * The problem that was brought to light by HTML_QuickForm with APC was that some files were being included both conditionally and unconditionally. The way APC solved this was simply to not cache the files or classes within them, obviously resulting in slower performance. An example of this is when an HTML element extends another element that is used. The user require_once's a driver, and the other driver conditionally includes it. * autoload is slower than direct unconditional include because it is processed at runtime in the exact way a conditional include is processed * There is no way to improve the performance of require_once other than to remove it and use require With these facts in place, it proves that although the performance difference is small for most users, using require_once has an unavoidable performance hit, and the more calls to require_once, the worse the hit, even with APC in its most optimized state. So yes, performance of *_once *is* an issue, contrary to earlier assertions based on Gopal's blog entries. The best performance is to be achieved by having a single include statement for each needed file in the entire application. For users who simply wish to try out a package, performance is not an issue, they just need to have an easy way to include all needed files. This should be done on the application level by including allfiles.php, or by setting up an __autoload(). Unlike PEAR, PEAR2 should support both models equally well. With PEAR, the best performance is physically impossible, and beginners often need to require_once several files just to get started. There were several synthetic benchmarks posted over the summer that support the relative performance of slow => fast with autoload => allfiles.php => custom allfiles.php, there's no need to rehash that argument. It is also true that the relative "performance" of ease of getting started is include '/path/to/PEAR2/Package/Name/allfiles.php'; => set up include_path/__autoload() => custom allfiles.php. In addition, creating a customized allfiles.php is relatively easy if autoload is possible. Simply use __autoload() and set up a shutdown function that var_dumps() get_included_files(). In short, after extensive research, I still support the initial proposal of removing require_once and adding allfiles.php and a README for each package. In my opinion, the next step is to figure out the best way to make this new system robust in the case of a missing file/class and to document how it should be used. I would like each package to have a top-level README.PackageName file, so that when it is installed or when it is unzipped, this file is easy to find. For instance: pyrus install PEAR2_PackageName PEAR2_PackageName installed into /full/path/to/pear2/ - read README.PEAR2_PackageName to get started the README would contain instructions on using allfiles, or on using __autoload(). This file could be autogenerated at packaging time for packages that don't have a customized one, as it would be the same for most packages. Within each file, dependencies, both internal and external, need to be clearly documented at the top of the file. Whether this should be done with only /** */ or additionally with class_exists() and exceptions or some other code-based solution is a decision that needs to be made. I would prefer beginning users to see a clear and simple error message if they try to directly include a file without a missing dependency. Making this possible in a way that does not adversely affect performance is important. That's all for now. Thanks, Greg

« previous php.pear.dev (#47835) next »