Я сделал небольшой тест, но перед результатами посмотрим, как работают эти функции. Вы можете прочитать исходный код PHP here. Существует french version of this answer, написанный ранее на этой неделе, хорошее время;).
Я также расскажу о is_file()
, так как он определен в одной и той же основной функции в источнике. По основной функции я говорю источник C, не доступный из языка PHP в ваши скрипты.
Из того, что я понимаю, file_exists()
и is_file()
являются дочерними элементами основной функции php_stat()
. Это весьма упрощено псевдокод процесса:
function php_stat($file)
{
'file_exists'
↳ virtual_file_ex($file)
↳ virtual_access($file)
'Windows'
↳ tsrm_win32_access($file)
↳ return access($file)
'Other systems'
↳ return access($file)
'is_file'
↳ return $file.st_mode == S_IFREG
}
И псевдо-код stream_resolve_include_path()
процесса:
function stream_resolve_include_path($file)
{
zend_resolve_path($file)
↳ php_resolve_path_for_zend($file)
↳ php_resolve_path($file)
↳ tsrm_realpath($file)
↳ return estrdup($file)
}
здесь, без числового результата в тесте, вы можете увидеть, как одна функция является дорогостоящей в ресурсе.
Код для теста:
function bench_file($file) {
$res = array();
$max = 1000000;
// is_file()
$res[] = microtime(1);
for ($i = 0; $i < $max; ++$i) {
if (is_file($file)) {
//
}
}
$res[] = microtime(1);
clearstatcache();
// file_exists()
$res[] = microtime(1);
for ($i = 0; $i < $max; ++$i) {
if (file_exists($file)) {
//
}
}
$res[] = microtime(1);
clearstatcache();
// stream_resolve_include_path()
$res[] = microtime(1);
for ($i = 0; $i < $max; ++$i) {
if (stream_resolve_include_path($file) !== false) {
//
}
}
$res[] = microtime(1);
printf(
'is_file = %f, file_exists = %f, stream_resolve_include_path = %f',
$res[1] - $res[0], $res[3] - $res[2], $res[5] - $res[4]
);
}
Давайте тест с existante файлом (1) и inexistant один (2):
1 : is_file = 0.218582, file_exists = 0.742195, stream_resolve_include_path = 1.626521
2 : is_file = 0.458983, file_exists = 0.644638, stream_resolve_include_path = 5.623289
Результаты говорят сами за себя;)
Benchmark v2 - just более простой способ добавить новые функции для тестирования.
function micro($func, $file) {
$max = 1000000;
$start = microtime(1);
for ($i = 0; $i < $max; ++$i) {
if ($func($file)) {
//
}
}
$end = microtime(1);
clearstatcache();
return $end - $start;
}
function bench_file($file) {
$res = array(
'is_file' => micro('is_file', $file),
'file_exists' => micro('file_exists', $file),
'stream_resolve_include_path' => micro('stream_resolve_include_path', $file)
);
$ret = '';
foreach ($res as $key => $value) {
$ret .= sprintf('%s = %f, ', $key, $value);
}
return trim($ret, ', ');
}
echo '<pre>', bench_file('file-ok'), "\n", bench_file('file-ko'), '</pre>';
Результаты:
is_file = 0.295752, file_exists = 0.852082, stream_resolve_include_path = 1.759607
is_file = 0.527770, file_exists = 0.724793, stream_resolve_include_path = 5.916151
Существует немного позвонить $funct()
, это объясняет несколько более высокие цифры.