Compare various methods to retrieve a string in a set

 time indexex time%
Start1135529618.9704-0.00%
switch1135529620.11531.14493083953863.94%
in_array1135529623.65723.541893005371112.20%
isset_hash1135529623.94810.290945768356321.00%
silent_hash1135529625.07321.12508296966553.87%
array_key_exists1135529629.17274.099440813064614.12%
strpos1135529630.62831.45562696456915.01%
preg_match1135529632.62721.99888586997996.88%
preg_match compiled1135529634.75232.12509465217597.32%
preg_match packed1135529636.74141.98910498619086.85%
dichotomy1135529643.30066.559184789657622.59%
compare1135529648.00984.709267854690616.22%
Stop1135529648.009800.00%
total-29.03945851326100.00%
<?php
require 'Benchmark/Timer.php';
set_time_limit (0);
$max = 10000;
    
/**
    * Validates a "region" (i.e. state) code
    *
    * @param string $region 2-letter state code
    * @return bool  true if $region is ok, false otherwise
    * @static
    */
function do_switch($region)
{
    switch (
strtoupper($region)) {
        case
'AC':
        case
'AP':
        case
'AL':
        case
'AM':
        case
'BA':
        case
'CE':
        case
'DF':
        case
'ES':
        case
'GO':
        case
'MA':
        case
'MT':
        case
'MS':
        case
'MG':
        case
'PA':
        case
'PB':
        case
'PR':
        case
'PE':
        case
'PI':
        case
'RJ':
        case
'RN':
        case
'RS':
        case
'RO':
        case
'RR':
        case
'SC':
        case
'SP':
        case
'SE':
        case
'TO':
            return
true;
    }
    return
false;
}
function
do_compare($region)
{
    return
$region =='AC'
        
|| $region =='AP'
        
|| $region =='AL'
        
|| $region =='AM'
        
|| $region =='BA'
        
|| $region =='CE'
        
|| $region =='DF'
        
|| $region =='ES'
        
|| $region =='GO'
        
|| $region =='MA'
        
|| $region =='MT'
        
|| $region =='MS'
        
|| $region =='MG'
        
|| $region =='PA'
        
|| $region =='PB'
        
|| $region =='PR'
        
|| $region =='PE'
        
|| $region =='PI'
        
|| $region =='RJ'
        
|| $region =='RN'
        
|| $region =='RS'
        
|| $region =='RO'
        
|| $region =='RR'
        
|| $region =='SC'
        
|| $region =='SP'
        
|| $region =='SE'
        
|| $region =='TO';
}
function
do_in_array($region)
{
    static
$regions = array('AC', 'AP', 'AL', 'AM', 'BA', 'CE', 'DF', 'ES',
     
'GO', 'MA', 'MT', 'MS', 'MG', 'PA', 'PB', 'PR', 'PE', 'PI', 'RJ', 'RN',
     
'RS', 'RO', 'RR', 'SC', 'SP', 'SE', 'TO');
    return
in_array($region, $regions);
}

function
do_isset_hash($region)
{
    static
$regions = array('AC'=>true, 'AP'=>true, 'AL'=>true, 'AM'=>true, 'BA'=>true, 'CE'=>true, 'DF'=>true, 'ES'=>true,
     
'GO'=>true, 'MA'=>true, 'MT'=>true, 'MS'=>true, 'MG'=>true, 'PA'=>true, 'PB'=>true, 'PR'=>true, 'PE'=>true, 'PI'=>true, 'RJ'=>true, 'RN'=>true,
     
'RS'=>true, 'RO'=>true, 'RR'=>true, 'SC'=>true, 'SP'=>true, 'SE'=>true, 'TO'=>true);
    return isset(
$regions[$region]);
}

function
do_silent_hash($region)
{
    static
$regions = array('AC'=>true, 'AP'=>true, 'AL'=>true, 'AM'=>true, 'BA'=>true, 'CE'=>true, 'DF'=>true, 'ES'=>true,
     
'GO'=>true, 'MA'=>true, 'MT'=>true, 'MS'=>true, 'MG'=>true, 'PA'=>true, 'PB'=>true, 'PR'=>true, 'PE'=>true, 'PI'=>true, 'RJ'=>true, 'RN'=>true,
     
'RS'=>true, 'RO'=>true, 'RR'=>true, 'SC'=>true, 'SP'=>true, 'SE'=>true, 'TO'=>true);
    return @
$regions[$region];
}

function
do_array_key_exists($region)
{
    static
$regions = array('AC'=>true, 'AP'=>true, 'AL'=>true, 'AM'=>true, 'BA'=>true, 'CE'=>true, 'DF'=>true, 'ES'=>true,
     
'GO'=>true, 'MA'=>true, 'MT'=>true, 'MS'=>true, 'MG'=>true, 'PA'=>true, 'PB'=>true, 'PR'=>true, 'PE'=>true, 'PI'=>true, 'RJ'=>true, 'RN'=>true,
     
'RS'=>true, 'RO'=>true, 'RR'=>true, 'SC'=>true, 'SP'=>true, 'SE'=>true, 'TO'=>true);
    return
array_key_exists($region, $regions);
}
function
do_strpos($region)
{
    static
$regions =
   
'..AC.AP.AL.AM.BA.CE.DF.ES.GO.MA.MT.MS.MG.PA.PB.PR.PE.PI.RJ.RN.RS.RO.RR.SC.SP.SE.TO.';
    return
strpos($regions, '.' . $region . '.');
}
function
do_preg_match($region)
{
    static
$regions =
   
'/^(?:AC|AP|AL|AM|BA|CE|DF|ES|GO|MA|MT|MS|MG|PA|PB|PR|PE|PI|RJ|RN|RS|RO|RR|SC|SP|SE|TO)$/';
    return
preg_match($regions, $region);
}
function
do_preg_match_compiled($region)
{
    static
$regions =
   
'/^(?:AC|AP|AL|AM|BA|CE|DF|ES|GO|MA|MT|MS|MG|PA|PB|PR|PE|PI|RJ|RN|RS|RO|RR|SC|SP|SE|TO)$/S';
    return
preg_match($regions, $region);
}
function
do_preg_match_packed($region)
{
    static
$regions =
   
'/^(?:A(?:C|P|L|M)|BA|CE|DF|ES|GO|M(?:A|T|S|G)|P(?:A|B|R|E|I)|R(?:J|N|S|O|R)|S(?:C|P|E)|TO)$/S';
    return
preg_match($regions, $region);
}
function
do_dichotomy($region)
{
    static
$regions = array('AC', 'AL', 'AM', 'AP', 'BA', 'CE', 'DF', 'ES',
     
'GO', 'MA', 'MG', 'MS', 'MT', 'PA', 'PB', 'PE', 'PI', 'PR', 'RJ', 'RN',
     
'RO', 'RR', 'RS', 'SC', 'SE', 'SP', 'TO', 'TO', 'TO', 'TO', 'TO', 'TO');
    
$i = 15;
    
$delta = 8;
    while (
$delta) {
        if (
$region == $regions[$i]) {
            return
true;
        }        
        if (
$region > $regions[$i]) {
            
$i += $delta;
        } else {
            
$i -= $delta;
        }
        
$delta = (int)($delta / 2);
    }
    return
$region == $regions[$i];
}
function
do_empty($region)
{
    return
true;
}
// test is made with all good codes and a few wrong
$test = array('AC', 66, 'AP', 'AL', 'false', 'AM', 'BA', 'x', 'CE', 'DF', 'ES', 'GO', 'MA', 'MT', 'jojo', 'MS', 'MG', 'PA', 'PB', 'argh', 'PR', 'PE', 'PI', 'RJ', 'RN', 'RS', 'RO', 'null', 'RR', 'SC', 'SP', 'SE', 'TO', 'chelas');

foreach (
$test as $reg) {
    
$res = do_switch($reg);
    if (
$res != do_in_array($reg)) {
        echo
"$reg not correct for in_array !\n";
    }
    if (
$res != do_isset_hash($reg)) {
        echo
"$reg not correct for isset_hash !\n";
    }
    if (
$res != do_silent_hash($reg)) {
        echo
"$reg not correct for silent hash !\n";
    }
    if (
$res != do_array_key_exists($reg)) {
        echo
"$reg not correct for array_key_exists !\n";
    }
    if (
$res != do_strpos($reg)) {
        echo
"$reg not correct for strpos !\n";
    }
    if (
$res != do_preg_match($reg)) {
        echo
"$reg not correct for preg_match !\n";
    }
    if (
$res != do_preg_match_compiled($reg)) {
        echo
"$reg not correct for preg_match_compiled !\n";
    }
    if (
$res != do_preg_match_packed($reg)) {
        echo
"$reg not correct for preg_match_packed !\n";
    }
    if (
$res != do_dichotomy($reg)) {
        echo
"$reg not correct for dichotomy !\n";
    }
    if (
$res != do_compare($reg)) {
        echo
"$reg not correct for compare !\n";
    }
}

$timer = new Benchmark_Timer();
$timer->start();

for (
$i = $max; $i--; ) {
    foreach (
$test as $reg) {
        
do_switch($reg);
    }
}
$timer->setMarker('switch');

for (
$i = $max; $i--; ) {
    foreach (
$test as $reg) {
        
do_in_array($reg);
    }
}
$timer->setMarker('in_array');

for (
$i = $max; $i--; ) {
    foreach (
$test as $reg) {
        
do_isset_hash($reg);
    }
}
$timer->setMarker('isset_hash');

for (
$i = $max; $i--; ) {
    foreach (
$test as $reg) {
        
do_silent_hash($reg);
    }
}
$timer->setMarker('silent_hash');

for (
$i = $max; $i--; ) {
    foreach (
$test as $reg) {
        
do_array_key_exists($reg);
    }
}
$timer->setMarker('array_key_exists');

for (
$i = $max; $i--; ) {
    foreach (
$test as $reg) {
        
do_strpos($reg);
    }
}
$timer->setMarker('strpos');

for (
$i = $max; $i--; ) {
    foreach (
$test as $reg) {
        
do_preg_match($reg);
    }
}
$timer->setMarker('preg_match');

for (
$i = $max; $i--; ) {
    foreach (
$test as $reg) {
        
do_preg_match_compiled($reg);
    }
}
$timer->setMarker('preg_match compiled');

for (
$i = $max; $i--; ) {
    foreach (
$test as $reg) {
        
do_preg_match_packed($reg);
    }
}
$timer->setMarker('preg_match packed');

for (
$i = $max; $i--; ) {
    foreach (
$test as $reg) {
        
do_dichotomy($reg);
    }
}
$timer->setMarker('dichotomy');

for (
$i = $max; $i--; ) {
    foreach (
$test as $reg) {
        
do_compare($reg);
    }
}
$timer->setMarker('compare');

// an empty loop to measure the external costs
for ($i = $max; $i--; ) {
    foreach (
$test as $reg) {
        
do_empty($reg);
    }
}
$timer->stop();

// make netto time by substracting the external cost
// using a modified version of Benchmark::timer with float results
$empty = $timer->markers['Stop'] - $timer->markers['compare'];
$i = 0;
foreach (
$timer->markers as $marker => $time) {
     
$timer->markers[$marker] -= $i++ * $empty;
}
$timer->display();
?>