pathinfo vs fnmatch
Asked Answered
C

5

7

There was a small debate regarding the speed of fnmatch over pathinfo here : how to check if file is php?

I wasn't totally convinced so decided to benchmark the two functions.

Using dynamic and static paths showed that pathinfo was faster.

Is my benchmarking logic and conclusion valid?

EDIT: Using mac php from cmd

PHP 5.3.0 (cli) (built: Jul 20 2009 13:56:33) Copyright (c) 1997-2009 The PHP Group Zend Engine v2.3.0, Copyright (c) 1998-2009 Zend Technologies

dynamic path pathinfo 3.2973630428314 fnmatch 3.4520659446716 x1.05

static path pathinfo 0.86487698554993 fnmatch 1.0420439243317 x1.2

mac xampp php from cmd

PHP 5.3.1 (cli) (built: Feb 27 2010 12:41:51) Copyright (c) 1997-2009 The PHP Group Zend Engine v2.3.0, Copyright (c) 1998-2009 Zend Technologies

dynamic path pathinfo 3.63922715187 fnmatch 4.99041700363 x1.37

static path pathinfo 1.03110480309 fnmatch 2.38929820061 x2.32

I include a sample of the results which are in seconds for 100,000 iterations on my machine :

dynamic path
pathinfo 3.79311800003
fnmatch 5.10071492195
x1.34

static path
pathinfo 1.03921294212
fnmatch 2.37709188461
x2.29

Code:

<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>
Crushing answered 22/4, 2010 at 18:31 Comment(4)
should be a CW since it's not a real question I guessJugular
It is a real question! Why do others reach a different conclusion?Crushing
How many times did you run the test? On multitasking machines, some tasks may be delayed, slowing down portions of code that may normally be quicker.Spartacus
I've run it many times and got the same results... I've updated my post with results from the command line.Crushing
C
1

I've upvoted all the answers but will answer my own question.

My benchmarking logic and conclusion is valid AND all the answers benchmarks are valid.

I've found the reason why, which has raised another question but rather making this post go off in a tangent and making it even longer I'll be opening another question. I'll put the new link here when I've done so.

Thanks for benchmarking for me!

EDIT: here is the part 2 question: (Pathinfo vs fnmatch part 2) Speed benchmark reversed on Windows and Mac

Crushing answered 3/5, 2010 at 16:12 Comment(0)
J
1

Running yours with

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

gives

dynamic path
pathinfo 3.4931519031525
fnmatch 2.8633069992065
x0.82

static path
pathinfo 0.83261299133301
fnmatch 0.28636598587036
x0.34

These four

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);
}

when run like this

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__);

and profiled on my machine from Zend Studio give

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

I find it somewhat annoying that no 4 is fastest, but that's what it says. And with 0.00000n seconds per call it's nothing to bother anyway.

Jugular answered 22/4, 2010 at 18:31 Comment(0)
O
1

My results are opposite of yours:

php -f 2693428.php
dynamic path
pathinfo 4.5834331512451
fnmatch 3.2174317836761
x0.7

static path
pathinfo 2.1787130832672
fnmatch 0.95714497566223
x0.44

Version

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
Orb answered 22/4, 2010 at 18:41 Comment(0)
V
1

Using the same benchmarking code

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
Verify answered 22/4, 2010 at 18:44 Comment(0)
S
1

I'll throw my results in here:

dynamic path
pathinfo 4.9078891277313
fnmatch 4.3466200828552
x0.89

static path
pathinfo 1.4787950515747
fnmatch 0.98351812362671
x0.67

But keep in mind my original comment on the question you linked to:

Concerning speed, fnmatch will out perform pathinfo 2:1 when used for this purpose.

Specific to branching on a particular extension.

Spartacus answered 22/4, 2010 at 18:51 Comment(0)
C
1

I've upvoted all the answers but will answer my own question.

My benchmarking logic and conclusion is valid AND all the answers benchmarks are valid.

I've found the reason why, which has raised another question but rather making this post go off in a tangent and making it even longer I'll be opening another question. I'll put the new link here when I've done so.

Thanks for benchmarking for me!

EDIT: here is the part 2 question: (Pathinfo vs fnmatch part 2) Speed benchmark reversed on Windows and Mac

Crushing answered 3/5, 2010 at 16:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.