<?xml version="1.0" encoding="UTF-8"?><!-- generator="wordpress/2.3.1" -->
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	>
<channel>
	<title>Comments on: PHP Performance tip: require versus require_once</title>
	<link>http://www.techyouruniverse.com/software/php-performance-tip-require-versus-require_once</link>
	<description>Musings about technology from a Geek</description>
	<pubDate>Wed, 10 Mar 2010 00:53:23 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.3.1</generator>
		<item>
		<title>By: Konstantin Rozinov</title>
		<link>http://www.techyouruniverse.com/software/php-performance-tip-require-versus-require_once#comment-2627</link>
		<dc:creator>Konstantin Rozinov</dc:creator>
		<pubDate>Thu, 02 Apr 2009 01:13:21 +0000</pubDate>
		<guid>http://www.techyouruniverse.com/software/php-performance-tip-require-versus-require_once#comment-2627</guid>
		<description>Nick,

I have updated results and conclusion to report.  Same test.php script and ab command as above, but different, more realistic, results.



RESULTS:
--------
The average time it took to run test.php once:
require('absolute_path'):      0.000830569960420
require('relative_path'):      0.000829198306664
require_once('absolute_path'): 0.000832904849136
require_once('relative_path'): 0.000824960252097

The average was computed by eliminating the 100 slowest and 100 fastest times, so a total of 800 (1000 - 200) times were used to compute the average time.  This was done to eliminate any unusual spikes or dips.

The question of how many stat() system calls were made can be answered as follows:
- If you run httpd -X and then do an strace -p , you can view the system calls that take place to process the request.
- The most important thing to note is if you run test.php continuously (as the ab test does above), the stat() calls only happen for the first request:

  first call to test.php (above):
  -------------------------------
  lstat64 ("/www", {st_mode=S_IFDIR&#124;0755, st_size=...
  lstat64 ("/www/includes", {st_mode=S_IFDIR&#124;0755,...
  lstat64 ("/www/includes/example.com", {st_mode=S...
  lstat64 ("/www/includes/example.com/code", {st_m...
  lstat64 ("/www/includes/example.com/code/conf", ...
  lstat64 ("/www/includes/example.com/code/conf/sql_servers.inc", {st_mode...
  open ("/www/includes/example.com/code/conf/sql_servers.inc", O_RDONLY) = 17
  
  subsequent calls to test.php:
  -----------------------------
  open ("/www/includes/example.com/code/conf/sql_servers.inc", O_RDONLY) = 17

- The lack of stat() system calls in the subsequent calls to test.php only happens when test.php is called continusly.  If you wait a certain period of time (about 1 minute or so), the stat() calls will happen again.
- This indicates that either the OS (Ubuntu Linux in my case), or Apache is "caching" or knows the results of the previous stat() calls, so it doesn't bother repeating them.
- When using absolute_path there are fewer stat() system calls.
- When using relative_path there are more stat() system calls because it has to start stat()ing from the current directory back up to / and then to the include/ directory.


CONCLUSIONS:
------------
- Try to use absolute_path when calling require*().
- The time difference between require_once() vs. require() is so tiny, it's almost always insignificant in terms of performance.  The one exception is if you have a very large application that has hundreds of require*() calls.
- When using APC opcode caching, the speed difference between the two is completely irrelevant.
- Use an opcode cache, like APC!

Konstantin Rozinov
krozinov [at] gmail</description>
		<content:encoded><![CDATA[<p>Nick,</p>
<p>I have updated results and conclusion to report.  Same test.php script and ab command as above, but different, more realistic, results.</p>
<p>RESULTS:<br />
&#8212;&#8212;&#8211;<br />
The average time it took to run test.php once:<br />
require(&#8217;absolute_path&#8217;):      0.000830569960420<br />
require(&#8217;relative_path&#8217;):      0.000829198306664<br />
require_once(&#8217;absolute_path&#8217;): 0.000832904849136<br />
require_once(&#8217;relative_path&#8217;): 0.000824960252097</p>
<p>The average was computed by eliminating the 100 slowest and 100 fastest times, so a total of 800 (1000 - 200) times were used to compute the average time.  This was done to eliminate any unusual spikes or dips.</p>
<p>The question of how many stat() system calls were made can be answered as follows:<br />
- If you run httpd -X and then do an strace -p , you can view the system calls that take place to process the request.<br />
- The most important thing to note is if you run test.php continuously (as the ab test does above), the stat() calls only happen for the first request:</p>
<p>  first call to test.php (above):<br />
  &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
  lstat64 ("/www", {st_mode=S_IFDIR|0755, st_size=&#8230;<br />
  lstat64 ("/www/includes", {st_mode=S_IFDIR|0755,&#8230;<br />
  lstat64 ("/www/includes/example.com", {st_mode=S&#8230;<br />
  lstat64 ("/www/includes/example.com/code", {st_m&#8230;<br />
  lstat64 ("/www/includes/example.com/code/conf", &#8230;<br />
  lstat64 ("/www/includes/example.com/code/conf/sql_servers.inc", {st_mode&#8230;<br />
  open ("/www/includes/example.com/code/conf/sql_servers.inc", O_RDONLY) = 17</p>
<p>  subsequent calls to test.php:<br />
  &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />
  open ("/www/includes/example.com/code/conf/sql_servers.inc", O_RDONLY) = 17</p>
<p>- The lack of stat() system calls in the subsequent calls to test.php only happens when test.php is called continusly.  If you wait a certain period of time (about 1 minute or so), the stat() calls will happen again.<br />
- This indicates that either the OS (Ubuntu Linux in my case), or Apache is "caching" or knows the results of the previous stat() calls, so it doesn&#8217;t bother repeating them.<br />
- When using absolute_path there are fewer stat() system calls.<br />
- When using relative_path there are more stat() system calls because it has to start stat()ing from the current directory back up to / and then to the include/ directory.</p>
<p>CONCLUSIONS:<br />
&#8212;&#8212;&#8212;&#8212;<br />
- Try to use absolute_path when calling require*().<br />
- The time difference between require_once() vs. require() is so tiny, it&#8217;s almost always insignificant in terms of performance.  The one exception is if you have a very large application that has hundreds of require*() calls.<br />
- When using APC opcode caching, the speed difference between the two is completely irrelevant.<br />
- Use an opcode cache, like APC!</p>
<p>Konstantin Rozinov<br />
krozinov [at] gmail</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Konstantin Rozinov</title>
		<link>http://www.techyouruniverse.com/software/php-performance-tip-require-versus-require_once#comment-2616</link>
		<dc:creator>Konstantin Rozinov</dc:creator>
		<pubDate>Wed, 01 Apr 2009 08:13:03 +0000</pubDate>
		<guid>http://www.techyouruniverse.com/software/php-performance-tip-require-versus-require_once#comment-2616</guid>
		<description>The script (test.php) is:

 function getmicrotime()
 {
    list($x,$y) = explode(' ',microtime());
    return ($x+$y);
 }

 $start_time = getmicrotime();
 
 /* 
  * Uncomment one at a time. 
  * sql_server.inc only contains define() statements.
  */

 //require('/www/includes/example.com/code/conf/sql_servers.inc');
 //require('../../includes/example.com/code/conf/sql_servers.inc');
 //require_once('/www/includes/example.com/code/conf/sql_servers.inc');
 //require_once('../../includes/example.com/code/conf/sql_servers.inc');
 
 $end_time = getmicrotime();
 
 $handle = fopen("/tmp/results", "ab+");
 fwrite($handle, ($end_time - $start_time) . "\n");
 fclose($handle);


Konstantin Rozinov</description>
		<content:encoded><![CDATA[<p>The script (test.php) is:</p>
<p> function getmicrotime()<br />
 {<br />
    list($x,$y) = explode(&#8217; &#8216;,microtime());<br />
    return ($x+$y);<br />
 }</p>
<p> $start_time = getmicrotime();</p>
<p> /*<br />
  * Uncomment one at a time.<br />
  * sql_server.inc only contains define() statements.<br />
  */</p>
<p> //require(&#8217;/www/includes/example.com/code/conf/sql_servers.inc&#8217;);<br />
 //require(&#8217;../../includes/example.com/code/conf/sql_servers.inc&#8217;);<br />
 //require_once(&#8217;/www/includes/example.com/code/conf/sql_servers.inc&#8217;);<br />
 //require_once(&#8217;../../includes/example.com/code/conf/sql_servers.inc&#8217;);</p>
<p> $end_time = getmicrotime();</p>
<p> $handle = fopen("/tmp/results", "ab+");<br />
 fwrite($handle, ($end_time - $start_time) . "\n");<br />
 fclose($handle);</p>
<p>Konstantin Rozinov</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Konstantin Rozinov</title>
		<link>http://www.techyouruniverse.com/software/php-performance-tip-require-versus-require_once#comment-2615</link>
		<dc:creator>Konstantin Rozinov</dc:creator>
		<pubDate>Wed, 01 Apr 2009 08:11:04 +0000</pubDate>
		<guid>http://www.techyouruniverse.com/software/php-performance-tip-require-versus-require_once#comment-2615</guid>
		<description>I ran some tests to see what's faster: require_once() vs require() and relative_path vs absolute_path.

METHODOLOGY:
The script (test.php):



I ran ab on the test.php script with a different require*() uncommented each time:
ab -n 1000 -c 10 www.example.com/test.php

RESULTS:
(how long it took to execute 1 call to test.php):
require('absolute_path'): 0.001522074937820
require('relative_path'): 0.000859447956085
require_once('absolute_path'): 0.001737765312195
require_once('relative_path'): 0.000952602624893

When using absolute_path there are fewer stat() system calls.
When using relative_path there are more stat() system calls.

CONCLUSIONS:
Using absolute_path is almost 2 times slower than using relative_path. 
Using require_once() is slower than require().


NOTES:
In your blog entry above, when you use relative_path, you only show 1 stat() call.  In my case, it stat()ed every directory leading to the relative_path and more...so one of us got wrong results in terms of the number of stat() calls.

Any feedback would be appreciated.

Konstantin Rozinov</description>
		<content:encoded><![CDATA[<p>I ran some tests to see what&#8217;s faster: require_once() vs require() and relative_path vs absolute_path.</p>
<p>METHODOLOGY:<br />
The script (test.php):</p>
<p>I ran ab on the test.php script with a different require*() uncommented each time:<br />
ab -n 1000 -c 10 <a href="http://www.example.com/test.php" rel="nofollow">www.example.com/test.php</a></p>
<p>RESULTS:<br />
(how long it took to execute 1 call to test.php):<br />
require(&#8217;absolute_path&#8217;): 0.001522074937820<br />
require(&#8217;relative_path&#8217;): 0.000859447956085<br />
require_once(&#8217;absolute_path&#8217;): 0.001737765312195<br />
require_once(&#8217;relative_path&#8217;): 0.000952602624893</p>
<p>When using absolute_path there are fewer stat() system calls.<br />
When using relative_path there are more stat() system calls.</p>
<p>CONCLUSIONS:<br />
Using absolute_path is almost 2 times slower than using relative_path.<br />
Using require_once() is slower than require().</p>
<p>NOTES:<br />
In your blog entry above, when you use relative_path, you only show 1 stat() call.  In my case, it stat()ed every directory leading to the relative_path and more&#8230;so one of us got wrong results in terms of the number of stat() calls.</p>
<p>Any feedback would be appreciated.</p>
<p>Konstantin Rozinov</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Generation 5 &#187; An Awesome Autoloader for PHP</title>
		<link>http://www.techyouruniverse.com/software/php-performance-tip-require-versus-require_once#comment-1975</link>
		<dc:creator>Generation 5 &#187; An Awesome Autoloader for PHP</dc:creator>
		<pubDate>Fri, 09 Jan 2009 21:19:26 +0000</pubDate>
		<guid>http://www.techyouruniverse.com/software/php-performance-tip-require-versus-require_once#comment-1975</guid>
		<description>[...] Wikia Developer Finds require_once() Slower Than require() Another Developer Finds Little Difference Yet Another Developer Finds It Depends On His Cache Configuration Rumor has it,  PHP 5.3 improves require_once() performance [...]</description>
		<content:encoded><![CDATA[<p>[&#8230;] Wikia Developer Finds require_once() Slower Than require() Another Developer Finds Little Difference Yet Another Developer Finds It Depends On His Cache Configuration Rumor has it,  PHP 5.3 improves require_once() performance [&#8230;]</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Recent Faves Tagged With "syscalls" : MyNetFaves</title>
		<link>http://www.techyouruniverse.com/software/php-performance-tip-require-versus-require_once#comment-1621</link>
		<dc:creator>Recent Faves Tagged With "syscalls" : MyNetFaves</dc:creator>
		<pubDate>Thu, 23 Oct 2008 06:05:21 +0000</pubDate>
		<guid>http://www.techyouruniverse.com/software/php-performance-tip-require-versus-require_once#comment-1621</guid>
		<description>[...] public links &#62;&#62; syscalls    PHP Performance tip: require versus require_once First saved by kbhardwaj &#124; 1 days ago      Vincenzo Iozzo: First post, me and my project First [...]</description>
		<content:encoded><![CDATA[<p>[&#8230;] public links &gt;&gt; syscalls    PHP Performance tip: require versus require_once First saved by kbhardwaj | 1 days ago      Vincenzo Iozzo: First post, me and my project First [&#8230;]</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: nick</title>
		<link>http://www.techyouruniverse.com/software/php-performance-tip-require-versus-require_once#comment-999</link>
		<dc:creator>nick</dc:creator>
		<pubDate>Thu, 07 Aug 2008 13:57:43 +0000</pubDate>
		<guid>http://www.techyouruniverse.com/software/php-performance-tip-require-versus-require_once#comment-999</guid>
		<description>Great question Tony. It seems like more followup testing is in order to come up with a "best practice" way of including files. Other things to consider:

) realpath_cache_size (as Clint pointed out)
) include vs require?
) PHP Autoloading
) Roll your own auto-loading (Although Rasmus warned me that this is the worst, because it uses the less efficient type of caching with APC)
) Behaviour of APC vs other accelerators

Hmm. Maybe I shouldn't do another write-up...

And as far as resolving conflicts, in the case above I chose that particular file because I knew it was only called once, so I could be  99% sure that it wouldn't load all those files again. It was a "load all these extensions" type file. It will be much more work to walk through the rest of the application.

One idea I had was to use something like this at the top of the files that were being included:
class_exists('ClassInFile') &#038;& return;
or this:
function_exists('functionInFile') &#038;& return;

That way if you accidentally re-included it, the file wouldn't be reparsed.

Hopefully this highlights the penalty with require_once though, and developers will think twice the next time, and just use require.</description>
		<content:encoded><![CDATA[<p>Great question Tony. It seems like more followup testing is in order to come up with a "best practice" way of including files. Other things to consider:</p>
<p>) realpath_cache_size (as Clint pointed out)<br />
) include vs require?<br />
) PHP Autoloading<br />
) Roll your own auto-loading (Although Rasmus warned me that this is the worst, because it uses the less efficient type of caching with APC)<br />
) Behaviour of APC vs other accelerators</p>
<p>Hmm. Maybe I shouldn&#8217;t do another write-up&#8230;</p>
<p>And as far as resolving conflicts, in the case above I chose that particular file because I knew it was only called once, so I could be  99% sure that it wouldn&#8217;t load all those files again. It was a "load all these extensions" type file. It will be much more work to walk through the rest of the application.</p>
<p>One idea I had was to use something like this at the top of the files that were being included:<br />
class_exists(&#8217;ClassInFile&#8217;) &#038;& return;<br />
or this:<br />
function_exists(&#8217;functionInFile&#8217;) &#038;& return;</p>
<p>That way if you accidentally re-included it, the file wouldn&#8217;t be reparsed.</p>
<p>Hopefully this highlights the penalty with require_once though, and developers will think twice the next time, and just use require.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Tony</title>
		<link>http://www.techyouruniverse.com/software/php-performance-tip-require-versus-require_once#comment-998</link>
		<dc:creator>Tony</dc:creator>
		<pubDate>Thu, 07 Aug 2008 12:35:49 +0000</pubDate>
		<guid>http://www.techyouruniverse.com/software/php-performance-tip-require-versus-require_once#comment-998</guid>
		<description>Nick:

How does this affect performance if we used absolute paths for require_once()?

How did you solve the conflicts of multiple files 'require' the same library?

file1.php - require('lib1.php');
file2.php - 
  require('lib1.php');
  require('file1.php');</description>
		<content:encoded><![CDATA[<p>Nick:</p>
<p>How does this affect performance if we used absolute paths for require_once()?</p>
<p>How did you solve the conflicts of multiple files &#8216;require&#8217; the same library?</p>
<p>file1.php - require(&#8217;lib1.php&#8217;);<br />
file2.php -<br />
  require(&#8217;lib1.php&#8217;);<br />
  require(&#8217;file1.php&#8217;);</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: nick</title>
		<link>http://www.techyouruniverse.com/software/php-performance-tip-require-versus-require_once#comment-984</link>
		<dc:creator>nick</dc:creator>
		<pubDate>Fri, 01 Aug 2008 23:03:49 +0000</pubDate>
		<guid>http://www.techyouruniverse.com/software/php-performance-tip-require-versus-require_once#comment-984</guid>
		<description>Good point Clint - I had assumed that everyone would already have realpath_cache_size set higher.

I talked to Rasmus about this recently at OSCON, and he said that realpath_cache definitely helps (epsecially for NFS), but that they can't cache *misses*, so it still has to stat all of the stats for files and directories that don't exist -- the ones that it had to go through while searching your include_path. 

So it's important to realpath_cache_size set higher for large apps, but the above benchmarks are still valid.</description>
		<content:encoded><![CDATA[<p>Good point Clint - I had assumed that everyone would already have realpath_cache_size set higher.</p>
<p>I talked to Rasmus about this recently at OSCON, and he said that realpath_cache definitely helps (epsecially for NFS), but that they can&#8217;t cache *misses*, so it still has to stat all of the stats for files and directories that don&#8217;t exist &#8212; the ones that it had to go through while searching your include_path. </p>
<p>So it&#8217;s important to realpath_cache_size set higher for large apps, but the above benchmarks are still valid.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Clint Byrum</title>
		<link>http://www.techyouruniverse.com/software/php-performance-tip-require-versus-require_once#comment-983</link>
		<dc:creator>Clint Byrum</dc:creator>
		<pubDate>Fri, 01 Aug 2008 21:46:00 +0000</pubDate>
		<guid>http://www.techyouruniverse.com/software/php-performance-tip-require-versus-require_once#comment-983</guid>
		<description>You don't mention the realpath cache and/or its effect (added in php 5.2.0 ...). Did you try just setting the realpath cache size bigger?

http://us2.php.net/manual/en/ini.core.php#ini.realpath-cache-size

16K isn't much room if you have hundreds of files, and lots of directories in your include_path.</description>
		<content:encoded><![CDATA[<p>You don&#8217;t mention the realpath cache and/or its effect (added in php 5.2.0 &#8230;). Did you try just setting the realpath cache size bigger?</p>
<p><a href="http://us2.php.net/manual/en/ini.core.php#ini.realpath-cache-size" rel="nofollow">http://us2.php.net/manual/en/ini.core.php#ini.realpath-cache-size</a></p>
<p>16K isn&#8217;t much room if you have hundreds of files, and lots of directories in your include_path.</p>
]]></content:encoded>
	</item>
</channel>
</rss>
