There's been a lot of discussion about the speed differences between using require_once() vs. require().
I was curious myself, so I ran some tests to see what's faster:
- require_once() vs require()
- using relative_path vs absolute_path
I also included results from strace for the number of stat() system calls. My results and conclusions below.
METHODOLOGY:
------------
The script (test.php):
<?php
$start_time = microtime(true);
$end_time = microtime(true);
$handle = fopen("/tmp/results", "ab+");
fwrite($handle, ($end_time - $start_time) . "\n");
fclose($handle);
?>
The test:
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:
--------
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 <pid_of_httpd>, 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|0755, st_size=...
lstat64 ("/www/includes", {st_mode=S_IFDIR|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