php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #28901 include_once() and require_once() could be *much* faster
Submitted: 2004-06-23 22:43 UTC Modified: 2004-06-24 16:03 UTC
From: sprice at wisc dot edu Assigned:
Status: Not a bug Package: Performance problem
PHP Version: 4.3.7 OS: Mac OS X 10.3.4
Private report: No CVE-ID: None
 [2004-06-23 22:43 UTC] sprice at wisc dot edu
Description:
------------
I use include_once() and require_once() quite a bit, as 
I would guess many others do. During a single page load, 
I might call for the same file from many functions, just 
to make sure things get defined correctly and in the 
correct order. I did some testing today, and I noticed 
that they both could be close to *two orders of 
magnitude* faster for multiple inclusions.

I have attached the PHP code that I used to test this. 
On my computer, when I use include_once() inside the for 
loop, it takes about 6.0 seconds. When I use 
improved_include_once(), it takes about 0.08 seconds. 
The same goes for require_once().

Could/Should something like this be implemented in PHP? 
It seems like a good idea, and you guys could do a more 
efficient implementation than I am able to do.

Reproduce code:
---------------
function getMicroTime(){
	list($usec, $sec) = explode( ' ', microtime() );
	return ((float)$usec + (float)$sec);
}

function improved_include_once($filename){
	if(!isset($GLOBALS['included_files'][$filename])){
		include_once($filename);
		$GLOBALS['included_files'][$filename] = TRUE;
	}
}

$start_time = getMicroTime();

for($i = 0; $i < 10000; $i++){
	include_once('my_file.inc');
}

echo (getMicroTime() - $start_time);


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2004-06-24 01:58 UTC] pollita@php.net
The internal include_once() performs additional checks which are not performed by your "improved" version.  For example, your version does not account for symbolic links, non-case sensitive file systems, or current working directory and include paths (when used with relative pathnames).

The good news is that the basic format of your "already included registry" is the essentially the same as what's used internally, so you were on the right track at least.
 [2004-06-24 16:03 UTC] sprice at wisc dot edu
True, but that is why my function calls include_once() 
after its check. It checks for the most common case 
first, where people use it how I described previously. 
It was my hope that this function would only ignore 
files which include_once() would also ignore, and by 
doing this it takes care of the simple, common, cases. 
Anything more complex than this gets fully parsed by 
include_once().

I realize now that it is possible to change the 
underlying directory structure or change the current 
working directory in order to make 
include_once('my_file.inc') and 
include_once('my_file.inc') give different files.

It seems a waste, though, that we can't speed up the 
function by several orders of magnitude because of a few 
edge cases. include_once() and require_once() are as 
slow as database accesses for me, even when the file has 
been included already.

Maybe you could make it a two-level registry, and any 
filesystem writes or directory changes clears the first 
level. But then we may be getting a little complex. But 
it would be a nice performance increase for me (and 
others, I suspect).
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Mar 28 09:01:26 2024 UTC