pathinfo vs fnmatch

Были небольшие дебаты относительно скорости fnmatch по pathinfo здесь: как проверить, является ли файл php?

Я не был полностью убежден, поэтому решил сравнить две функции.

Использование динамических и статических путей показало, что pathinfo был быстрее.

Является ли моя эталонная логика и заключение действительными?

EDIT : использование mac php из cmd

PHP 5.3.0 (cli) (построено: 20 июля 2009 13:56:33) Copyright (c) 1997-2009 PHP Group Zend Engine v2.3.0, Copyright (c) 1998-2009 Zend Technologies

динамический путь pathinfo 3.2973630428314 fnmatch 3.4520659446716 x1.05

static path pathinfo 0.86487698554993 fnmatch 1.0420439243317 x1.2

mac xampp php от cmd

PHP 5.3.1 (cli) (построено: 27.02.2010 12:41:51) Copyright (c) 1997-2009 PHP Group Zend Engine v2.3.0, Copyright (c) 1998-2009 Zend Technologies

динамический путь pathinfo 3.63922715187 fnmatch 4.99041700363 x1.37

static path pathinfo 1.03110480309 fnmatch 2.38929820061 x2.32

Я включаю образец результатов, которые в секундах для 100 000 итераций на моей машине:

dynamic path pathinfo 3.79311800003 fnmatch 5.10071492195 x1.34 static path pathinfo 1.03921294212 fnmatch 2.37709188461 x2.29 

Код:

 <pre> <?php $iterations=100000; // Benchmark with dynamic file path print("dynamic path\n"); $i=$iterations; $t1=microtime(true); while($i-->0){ $f='/'.uniqid().'/'.uniqid().'/'.uniqid().'/'.uniqid().'.php'; if(pathinfo($f,PATHINFO_EXTENSION)=='php') $d=uniqid(); } $t2=microtime(true) - $t1; print("pathinfo $t2\n"); $i=$iterations; $t1=microtime(true); while($i-->0){ $f='/'.uniqid().'/'.uniqid().'/'.uniqid().'/'.uniqid().'.php'; if(fnmatch('*.php',$f)) $d=uniqid(); } $t3 = microtime(true) - $t1; print("fnmatch $t3\n"); print('x'.round($t3/$t2,2)."\n\n"); // Benchmark with static file path print("static path\n"); $f='/'.uniqid().'/'.uniqid().'/'.uniqid().'/'.uniqid().'.php'; $i=$iterations; $t1=microtime(true); while($i-->0) if(pathinfo($f,PATHINFO_EXTENSION)=='php') $d=uniqid(); $t2=microtime(true) - $t1; print("pathinfo $t2\n"); $i=$iterations; $t1=microtime(true); while($i-->0) if(fnmatch('*.php',$f)) $d=uniqid(); $t3=microtime(true) - $t1; print("fnmatch $t3\n"); print('x'.round($t3/$t2,2)."\n\n"); ?> </pre> в <pre> <?php $iterations=100000; // Benchmark with dynamic file path print("dynamic path\n"); $i=$iterations; $t1=microtime(true); while($i-->0){ $f='/'.uniqid().'/'.uniqid().'/'.uniqid().'/'.uniqid().'.php'; if(pathinfo($f,PATHINFO_EXTENSION)=='php') $d=uniqid(); } $t2=microtime(true) - $t1; print("pathinfo $t2\n"); $i=$iterations; $t1=microtime(true); while($i-->0){ $f='/'.uniqid().'/'.uniqid().'/'.uniqid().'/'.uniqid().'.php'; if(fnmatch('*.php',$f)) $d=uniqid(); } $t3 = microtime(true) - $t1; print("fnmatch $t3\n"); print('x'.round($t3/$t2,2)."\n\n"); // Benchmark with static file path print("static path\n"); $f='/'.uniqid().'/'.uniqid().'/'.uniqid().'/'.uniqid().'.php'; $i=$iterations; $t1=microtime(true); while($i-->0) if(pathinfo($f,PATHINFO_EXTENSION)=='php') $d=uniqid(); $t2=microtime(true) - $t1; print("pathinfo $t2\n"); $i=$iterations; $t1=microtime(true); while($i-->0) if(fnmatch('*.php',$f)) $d=uniqid(); $t3=microtime(true) - $t1; print("fnmatch $t3\n"); print('x'.round($t3/$t2,2)."\n\n"); ?> </pre> в <pre> <?php $iterations=100000; // Benchmark with dynamic file path print("dynamic path\n"); $i=$iterations; $t1=microtime(true); while($i-->0){ $f='/'.uniqid().'/'.uniqid().'/'.uniqid().'/'.uniqid().'.php'; if(pathinfo($f,PATHINFO_EXTENSION)=='php') $d=uniqid(); } $t2=microtime(true) - $t1; print("pathinfo $t2\n"); $i=$iterations; $t1=microtime(true); while($i-->0){ $f='/'.uniqid().'/'.uniqid().'/'.uniqid().'/'.uniqid().'.php'; if(fnmatch('*.php',$f)) $d=uniqid(); } $t3 = microtime(true) - $t1; print("fnmatch $t3\n"); print('x'.round($t3/$t2,2)."\n\n"); // Benchmark with static file path print("static path\n"); $f='/'.uniqid().'/'.uniqid().'/'.uniqid().'/'.uniqid().'.php'; $i=$iterations; $t1=microtime(true); while($i-->0) if(pathinfo($f,PATHINFO_EXTENSION)=='php') $d=uniqid(); $t2=microtime(true) - $t1; print("pathinfo $t2\n"); $i=$iterations; $t1=microtime(true); while($i-->0) if(fnmatch('*.php',$f)) $d=uniqid(); $t3=microtime(true) - $t1; print("fnmatch $t3\n"); print('x'.round($t3/$t2,2)."\n\n"); ?> </pre> 

Мои результаты противоположны вашим:

 php -f 2693428.php dynamic path pathinfo 4.5834331512451 fnmatch 3.2174317836761 x0.7 static path pathinfo 2.1787130832672 fnmatch 0.95714497566223 x0.44 

Версия

 PHP 5.3.0 (cli) (built: Jun 29 2009 21:25:23) Copyright (c) 1997-2009 The PHP Group Zend Engine v2.3.0, Copyright (c) 1998-2009 Zend Technologies 

Использование одного и того же кода бенчмаркинга

 dynamic path pathinfo 2.6542711257935 fnmatch 1.9943950176239 x0.75 static path pathinfo 1.1711349487305 fnmatch 0.54186105728149 x0.46 PHP Version 5.3.1 Build Date Nov 20 2009 17:20:57 Compiler MSVC6 (Visual C++ 6.0) Architecture x86 Thread Safety enabled Zend Memory Manager enabled Zend Multibyte Support disabled 

Запуск с помощью

 PHP 5.3.2 (cgi-fcgi) (built: Mar 3 2010 20:47:00) Copyright (c) 1997-2010 The PHP Group Zend Engine v2.3.0, Copyright (c) 1998-2010 Zend Technologies with Zend Debugger v5.3, Copyright (c) 1999-2010, by Zend Technologies 

дает

 dynamic path pathinfo 3.4931519031525 fnmatch 2.8633069992065 x0.82 static path pathinfo 0.83261299133301 fnmatch 0.28636598587036 x0.34 

Эти четыре

 function hasExtension1($ext, $filename) { return !strcasecmp(pathinfo($filename, PATHINFO_EXTENSION), $ext); } function hasExtension2($ext, $filename) { return fnmatch("*.$ext", $filename, FNM_CASEFOLD); } function hasExtension3($ext, $filename) { return strripos($filename, $ext) === strlen($filename) - strlen($ext); } function hasExtension4($ext, $filename) { return !strcasecmp(substr($filename, -strlen($ext)), $ext); } 

при запуске

 for($i=0;$i<10000;$i++) hasExtension1('php', __FILE__); for($i=0;$i<10000;$i++) hasExtension2('php', __FILE__); for($i=0;$i<10000;$i++) hasExtension3('php', __FILE__); for($i=0;$i<10000;$i++) hasExtension4('php', __FILE__); 

и профилированные на моей машине от Zend Studio дают

 Average Mean Time = 0.000007 Average Mean Time = 0.000006 Average Mean Time = 0.000005 Average Mean Time = 0.000003 

Я нахожу это несколько раздражающим, что нет 4 быстрее, но это то, что он говорит. И с 0.00000n секунд за звонок ничто так не беспокоит.

Я приведу свои результаты здесь:

 dynamic path pathinfo 4.9078891277313 fnmatch 4.3466200828552 x0.89 static path pathinfo 1.4787950515747 fnmatch 0.98351812362671 x0.67 

Но имейте в виду мой оригинальный комментарий по вопросу, к которому вы связались:

Что касается скорости, fnmatch выйдет из режима pathinfo 2: 1 при использовании для этой цели.

Конкретно для ветвления на конкретном расширении.

Я поддержал все ответы, но отвечу на мой собственный вопрос.

Моя логика и заключение по бенчмаркированию верны, и все тестовые тесты являются действительными.

Я нашел причину, по которой поднял еще один вопрос, но вместо того, чтобы сделать этот пост в касательной и сделать его еще длиннее, я открою еще один вопрос. Я положу новую ссылку здесь, когда я это сделаю.

Спасибо за бенчмаркинг для меня!

EDIT: вот вопрос части 2: (Pathinfo vs fnmatch part 2) Тест скорости, измененный на Windows и Mac