J'ai fait un petit benchmark, mais avant les résultats, voyons comment fonctionnent ces fonctions. Vous pouvez lire le code source PHP here. Il ya un french version of this answer, écrit plus tôt dans la semaine, bon timing;).
Je parlerai aussi de is_file()
, car il est défini dans la même fonction de base dans la source. Par fonction de base, je dis la source C, pas accessible depuis le langage PHP dans vos scripts. De ce que je comprends, file_exists()
et is_file()
sont les enfants de la fonction de base php_stat()
deC'est le pseudo-code très simplifiée du processus:
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
}
Et le pseudo-code du processus 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)
}
A partir de là, sans résultat numérique d'une référence, vous pouvez voir comment une fonction est chère en ressource.
Le code de la référence:
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]
);
}
test Let avec un fichier existante (1) et un 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
Les résultats parlent d'eux-mêmes;)
Benchmark v2 - juste un moyen plus facile d'ajouter de nouvelles fonctions à tester.
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>';
Résultats:
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
Il y a un peu de frais pour appeler $funct()
, ce qui explique le nombre légèrement plus élevé.