views:

114

answers:

3

I need to extract the virtual host name of a HTTP request. Since this willl be done for every request, I´m searching for the fastest way to do this.

The following code and times are just some of the ways I had studied.

So, there is some faster way to do this?

$hostname = "alphabeta.gama.com";

$iteractions = 100000;

//While Test

$time_start = microtime(true);
for($i=0;$i < $iteractions; $i++){
    $vhost = "";
    while(($i < 20) && ($hostname{$i} != '.')) $vhost .= $hostname{$i++};
}

$time_end = microtime(true);
$timewhile = $time_end - $time_start;

//Regexp Test
$time_start = microtime(true);
for($i=0; $i<$iteractions; $i++){
    $vhost = "";
    preg_match("/([A-Za-z])*/", $hostname ,$vals);
    $vhost = $vals[0];
}
$time_end = microtime(true);
$timeregex = $time_end - $time_start;

//Substring Test
$time_start = microtime(true);
for($i=0;$i<$iteractions;$i++){
    $vhost = "";
    $vhost = substr($hostname,0,strpos($hostname,'.'));
}
$time_end = microtime(true);
$timesubstr = $time_end - $time_start;

//Explode Test
$time_start = microtime(true);
for($i=0;$i<$iteractions;$i++){
    $vhost = "";
    list($vhost) = explode(".",$hostname);
}
$time_end = microtime(true);
$timeexplode = $time_end - $time_start;

//Strreplace Test. Must have the final part of the string fixed.
$time_start = microtime(true);
for($i=0;$i<$iteractions;$i++){
    $vhost = "";
    $vhost = str_replace(".gama.com","",$hostname);
}
$time_end = microtime(true);
$timereplace = $time_end - $time_start;

echo "While   :".$timewhile."\n";
echo "Regex   :".$timeregex."\n";
echo "Substr  :".$timesubstr."\n";
echo "Explode :".$timeexplode."\n";
echo "Replace :".$timereplace."\n";

And as result timings:

While   :0.0886390209198
Regex   :1.22981309891
Substr  :0.338994979858
Explode :0.450794935226
Replace :0.33411693573
+5  A: 

You could try the strtok() function:

$vhost = strtok($hostname, ".")

It's faster than a correct version of your while loop, and much more readable.

Ville Laurikari
Strtok timing :0.234637975693
Renato Aquino
@Ville Nice idea. @Renato, this is an improvment of about 2 microseconds from the slowest one. nice work. lol
Byron Whitlock
By the way, since speed is so important to you, are you using a PHP accelerator of some sort?
Ville Laurikari
Hey Ville,I´m accepting your answer. It´s not faster then the while option, but it´s trully much more readable.Thanks!!
Renato Aquino
+3  A: 

I would do it the substr() way.

$vhost = substr($host, 0, strstr($host, "."));

And I really don't think that the way how you split this string would affect performance in any real-world program. 100 000 iterations is quite huge... ;-)

Alex
Alex, you, Ivan, Byron and any other person who says that it´s a waste of time 'this optimization' in a real world application are right.I´m just looking for the answer to the question: "Is there any faster way to do this?"Thanks for your answer.
Renato Aquino
Alright. Out of interest, how fast is substr($host, 0, strstr($host, "."))?
Alex
strpos instead of strstr should be faster.
Alix Axel
strstr does not work anyway, my fault. You gotta use strpos.
Alex
A: 
<?php
$iterations = 100000;
$fullhost = 'subdomain.domain.tld';

$start = microtime(true);

for($i = 0; $i < $iterations; $i++) 
{
    $vhost = substr($fullhost, 0, strpos($fullhost, '.'));
}

$total = microtime(true) - $start;
printf( 'extracted %s from %s %d times in %s seconds', $vhost, $fullhost, $iterations, number_format($total,5));
?>

extracted subdomain from subdomain.domain.tld 100000 times in 0.44695 seconds

But that was while encoding video, so it will likely be faster under better circumstances.

Kris
hehe, i missed the fact you already had this in your code but notied the kinda awkward (to me) strstr usage of Alex and i felt like trying this.
Kris
Thanks for trying Kris.
Renato Aquino