Monday 1 December 2008

php speed testing

Woke up this morning about 7.50am. The sky was clear and there was a slight mist. Had a shower etc and breakfast, then went in the garden. It was slightly frosty, but not really frosty, like it had been below freezing but no dew had fallen. The pond was frozen over, although the ice was only about 3mm thick.

I came back in and vacuumed my room and made my bed. Then I checked hotukdeals and my email. I did some work testing different ways of printing a select box of countries. By lunch time the sky had come over overcast.

After lunch I did more work testing different ways of printing a select box of countries. I checked hotukdeals, my email, deviantart and thewebsqueeze.

Below are the details of the tests I did for generating a select box of countries, with a random country selected as the default value. The actual pages were written in valid HTML 4.01 Strict, and timed in PHP from the top of the page (before the headers) to the end of the body where the processed time is written to the page. I have written the scripts below in the format Title - Time taken for PHP to process in seconds, followed by the page code. The timings given here are all the average out of 12 runs for creating 3 select boxes of countries. Further down the page I have a table with the timings for creating 3 selects, creating 1 select and also my conclusions.


Javascript & PHP String - 0.001700
<script type="text/javascript">
function goh()
{
var time = new Date();
var selects = document.getElementById('myForm').getElementsByTagName('select');
for (var i=0; i<selects.length; i++)
{
selects[i].selectedIndex = selects[i].name.substr(13);
selects[i].name = selects[i].id;
}
alert(new Date() - time);
}
</script>
</head>

<body onload="goh()">
<form action="" method="post" id="myForm">
<div>
<?php
$countriesList = '
<option value="0">Please select</option>
<option value="1">Afghanistan</option>
<option value="2">&Aring;land Islands</option>
...
<option value="245">Zambia</option>
<option value="246">Zimbabwe</option>
</select><br>';


for($i=0; $i<3; $i++)
{
$countryNo = rand(1,246);
echo '<select name="countrySelect'.$countryNo.'" size="1" id="countrySelect'.$countryNo.'">';
echo $countriesList;
}?>
</form>



Javascript - 0.002459
<script type="text/javascript">
function goh()
{
var time = new Date();
var selects = document.getElementById('myForm').getElementsByTagName('select');
for (var i=0; i<selects.length; i++)
{
selects[i].selectedIndex = selects[i].name.substr(13);
selects[i].name = selects[i].id;
}
alert(new Date() - time);
}
</script>
</head>

<body onload="goh()">
<form action="" method="post" id="myForm">
<div>
<?php
for($i=0; $i<3; $i++)
{
$countryNo = rand(1,246);
echo '<select name="countrySelect'.$countryNo.'" size="1" id="countrySelect'.$countryNo.'">';?>
<option value="0">Please select</option>
<option value="1">Afghanistan</option>
<option value="2">&Aring;land Islands</option>
...
<option value="245">Zambia</option>
<option value="246">Zimbabwe</option>
</select><br><?php
}?>
</form>



PHP Array - 0.002322
<form action="" method="post" id="myForm">
<div>
<?php
$countries = array('<option value="0">Please select</option>',
'<option value="1">Afghanistan</option>',
'<option value="2">&Aring;land Islands</option>',
...
'<option value="245">Zambia</option>',
'<option value="246">Zimbabwe</option>'
);


for($i=0; $i<3; $i++)
{
$countryNo = rand(1,246);
echo '<select name="countrySelect'.$countryNo.'" size="1" id="countrySelect'.$countryNo.'">';

$selectedCountry = $countries[$countryNo];
$countries[$countryNo] = split("\"$countryNo\"", $countries[$countryNo]);
$countries[$countryNo] = implode('"'.$countryNo.'" selected="selected"', $countries[$countryNo]);
echo implode("\n", $countries);
$countries[$countryNo] = $selectedCountry;
?></select><br><?php
}
?>
</div>
</form>




PHP Array Foreach Loop - 0.002297
<form action="" method="post" id="myForm">
<div>
<?php
$countries = array('<option value="0">Please select</option>',
'<option value="1">Afghanistan</option>',
'<option value="2">&Aring;land Islands</option>',
...
'<option value="245">Zambia</option>',
'<option value="246">Zimbabwe</option>'
);


for($i=0; $i<3; $i++)
{
$countryNo = rand(1,246);
echo '<select name="countrySelect'.$countryNo.'" size="1" id="countrySelect'.$countryNo.'">';
$selectedCountry = $countries[$countryNo];
$countries[$countryNo] = str_replace("\"$countryNo\"", '"'.$countryNo.'" selected="selected"', $countries[$countryNo]);
foreach($countries as $tmp)
{
echo "$tmp\n";
}
$countries[$countryNo] = $selectedCountry;
?></select><br><?php
}
?>
</div>
</form>



PHP Array Foreach Loop If Else - 0.002795
<form action="" method="post" id="myForm">
<div>
<?php
$countries = array('<option value="0">Please select</option>',
'<option value="1">Afghanistan</option>',
'<option value="2">&Aring;land Islands</option>',
...
'<option value="245">Zambia</option>',
'<option value="246">Zimbabwe</option>'
);


for($i=0; $i<3; $i++)
{
$countryNo = rand(1,246);
echo '<select name="countrySelect'.$countryNo.'" size="1" id="countrySelect'.$countryNo.'">';
for($j=0; $j<count($countries); $j++)
{
echo $j != $countryNo ? $countries[$j] : str_replace("\"$countryNo\"", '"'.$countryNo.'" selected="selected"', $countries[$j]);
}
?></select><br><?php
}
?>
</div>
</form>



PHP Array Foreach LoopV2 - 0.002428
<form action="" method="post" id="myForm">
<div>
<?php
$countries = array('0">Please select</option>',
'1">Afghanistan</option>',
'2">&Aring;land Islands</option>',
...
'245">Zambia</option>',
'246">Zimbabwe</option>'
);


for($i=0; $i<3; $i++)
{
$countryNo = rand(1,246);
echo '<select name="countrySelect'.$countryNo.'" size="1" id="countrySelect'.$countryNo.'">';
$selectedCountry = $countries[$countryNo];
$countries[$countryNo] = str_replace("\"$countryNo\"", '"'.$countryNo.'" selected="selected"', $countries[$countryNo]);
foreach($countries as $tmp)
{
echo "<option value=\"$tmp\n";
}
$countries[$countryNo] = $selectedCountry;
?></select><br><?php
}
?>
</div>
</form>



PHP Array Foreach LoopV3 - 0.002541
<form action="" method="post" id="myForm">
<div>
<?php
$countries = array('0">Please select</option>',
'1">Afghanistan</option>',
'2">&Aring;land Islands</option>',
...
'245">Zambia</option>',
'246">Zimbabwe</option>'
);
$jim = '<option value="';

for($i=0; $i<3; $i++)
{
$countryNo = rand(1,246);
echo '<select name="countrySelect'.$countryNo.'" size="1" id="countrySelect'.$countryNo.'">';
$selectedCountry = $countries[$countryNo];
$countries[$countryNo] = str_replace("$countryNo\"", $countryNo.'" selected="selected"', $countries[$countryNo]);
foreach($countries as $tmp)
{
echo "$jim$tmp\n";
}
$countries[$countryNo] = $selectedCountry;
?></select><br><?php
}
?>
</div>
</form>



PHP Array V2 - 0.002216
<form action="" method="post" id="myForm">
<div>
<?php
$countries = array('<option value="0">Please select</option>',
'<option value="1">Afghanistan</option>',
'<option value="2">&Aring;land Islands</option>',
...
'<option value="245">Zambia</option>',
'<option value="246">Zimbabwe</option>'
);


for($i=0; $i<3; $i++)
{
$countryNo = rand(1,246);
echo '<select name="countrySelect'.$countryNo.'" size="1" id="countrySelect'.$countryNo.'">';
$selectedCountry = $countries[$countryNo];
$countries[$countryNo] = str_replace("\"$countryNo\"", '"'.$countryNo.'" selected="selected"', $countries[$countryNo]);
echo implode("\n", $countries);
$countries[$countryNo] = $selectedCountry;
?></select><br><?php
}
?>
</div>
</form>



PHP SQL - 0.008532
<?php
//Connect to the database
$conn = new mysqli('localhost', 'username', 'password', 'database');
if(mysqli_connect_errno())
{$error = 'Error connecting to database';}
else
{$conn->set_charset('utf8');} //Country names are in UTF8 encoding

?>
...
<body>
<form action="" method="post" id="myForm">
<div>
<?php
for($i=0; $i<3; $i++)
{
$countryNo = rand(1,246);
echo '<select name="countrySelect'.$countryNo.'" size="1" id="countrySelect'.$countryNo.'">';
if($result = $conn->query('SELECT * FROM Country'))
{
while($row = $result->fetch_row())
{
echo '<option value="'.$row[0].'"';
if($row[0] == $countryNo){echo ' selected="selected"';}
echo ">$row[1]</option>\n";
}
}?></select><br><?php
}?>
</div>
</form>



PHP String - 0.002380
<form action="" method="post" id="myForm">
<div>
<?php
$countriesList = '
<option value="0">Please select</option>
<option value="1">Afghanistan</option>
<option value="2">&Aring;land Islands</option>
...
<option value="245">Zambia</option>
<option value="246">Zimbabwe</option>
</select><br>';


for($i=0; $i<3; $i++)
{
$countryNo = rand(1,246);
echo '<select name="countrySelect'.$countryNo.'" size="1" id="countrySelect'.$countryNo.'">';
echo str_replace("\"$countryNo\"", '"'.$countryNo.'" selected="selected"', $countriesList);
}?>
</form>



SQL - 0.010013
<?php
//Connect to the database
$conn = new mysqli('localhost', 'username', 'password', 'database');
if(mysqli_connect_errno())
{$error = 'Error connecting to database';}
else
{$conn->set_charset('utf8');} //Country names are in UTF8 encoding


$time = microtime();
?>
...
<form action="" method="post" id="myForm">
<div>
<?php
for($i=0; $i<3; $i++)
{
$countryNo = rand(1,246);
echo '<select name="countrySelect'.$countryNo.'" size="1" id="countrySelect'.$countryNo.'">';
$sql = 'SELECT CONCAT(\'<option value="\', `Key`, \'"\', IF(`Key` = '.$countryNo.', \' selected="selected"\', \'\'), \'>\', Country, \'</option>\n\') FROM Country';
if($result = $conn->query($sql))
{
while($row = $result->fetch_row())
{echo $row[0];}
}
if($conn->errno){echo $conn->error;}
?></select><br><?php
}?>
</div>
</form>



Results table

Print 3 select boxes of countries






Print 1 select box of countries


PHP Array SQL Javascript PHP SQL Javascript & PHP String PHP String PHP Array V2 PHP Array Foreach Loop PHP Array Foreach Loop If Else PHP Array Foreach LoopV2 PHP Array Foreach LoopV3
PHP Array SQL Javascript PHP SQL Javascript & PHP String PHP String PHP Array V2

0.003107 0.008904 0.002924 0.005858 0.001387 0.002100 0.002469 0.002190 0.002541 0.002128 0.001941
0.000559 0.003171 0.000542 0.004350 0.000909 0.000484 0.000554

0.002045 0.010813 0.002375 0.009637 0.001305 0.002183 0.002359 0.002332 0.003224 0.001624 0.003790
0.001282 0.004007 0.000809 0.002662 0.000849 0.001107 0.001212

0.001863 0.010696 0.001655 0.009143 0.001936 0.003736 0.002863 0.002348 0.002739 0.002989 0.002811
0.001322 0.004992 0.000853 0.003926 0.000338 0.001203 0.001286

0.003921 0.011951 0.003290 0.009000 0.001324 0.001911 0.002110 0.002965 0.003409 0.001845 0.003745
0.001238 0.004763 0.000643 0.002973 0.000307 0.000996 0.000979

0.002585 0.009032 0.003754 0.007923 0.001268 0.003286 0.001495 0.001473 0.001954 0.003301 0.002689
0.001148 0.003378 0.000694 0.002591 0.000853 0.001318 0.000564

0.001442 0.011076 0.002411 0.009588 0.003025 0.002781 0.002083 0.002643 0.002905 0.003148 0.003202
0.001087 0.003782 0.001174 0.005099 0.000490 0.001046 0.000910

0.002501 0.009241 0.002010 0.005768 0.001481 0.002257 0.001871 0.001903
0.002678 0.001825
0.000564 0.003946 0.000896 0.003508 0.000803 0.000427 0.001347

0.002066 0.009481 0.002031 0.007556 0.002009 0.001394 0.001738 0.001710
0.001717 0.002875
0.001050 0.003560 0.000677 0.003571 0.000323 0.000935 0.001234

0.002126 0.007343 0.003008 0.009607 0.001936 0.002638 0.002843 0.002819
0.001782 0.001426
0.000994 0.004837 0.001099 0.002604 0.000845 0.000407 0.000551

0.001761 0.010238 0.001826 0.010639 0.002199 0.001556 0.002826 0.003268
0.001707 0.001811
0.001543 0.003902 0.000855 0.003421 0.000801 0.001033 0.001404

0.001569 0.011358 0.002194 0.009322 0.001272 0.002398 0.002016 0.002184
0.002827 0.002351
0.001328 0.002673 0.000721 0.002808 0.000384 0.000964 0.001215

0.002882 0.010021 0.002035 0.008340 0.001258 0.002314 0.001921 0.001729
0.003393 0.002028
0.001277 0.003436 0.000799 0.003041 0.000294 0.001177 0.000957
Avg 0.002322 0.010013 0.002459 0.008532 0.001700 0.002380 0.002216 0.002297 0.002795 0.002428 0.002541
0.001116 0.003871 0.000814 0.003380 0.000600 0.000925 0.001018

























Javascript & PHP String is 30.3627450980392% faster than PHP Array V2










Javascript & PHP String is 69.7192884936076% faster than PHP Array V2



Conclusions

  • Building up the list from MySQL is comparatively slow. Although still fast at around 1/100s I don't think it's worth using for static data like a list of countries.

  • I was surprised to see that when creating 3 select boxes, it is faster to use a PHP variable containing all the <options> in a string (Javascript & PHP String) than it was to have them encoded inside the loop and breakout of PHP when you get to them (Javascript). Even more surprising is that it is still faster when only running through the loop once.

  • Selecting the country using javascript seems to be quite a bit faster than doing it with PHP. I tried timing the javascript as well, but just got a '1', so think the javascript pretty much doesn't take any time to work.

  • There are 2 problems with using javascript to select the country:
    1. The user may have javascript turned off or using a browser that doesn't support javascript.
    2. You can't trigger the javascript to select the country until the page has loaded. So if your select box is near the top of the page, which lots of slow loading code below it, the user may see/use the select box before javascript selects the country

    So for general use I'd use the PHP Array V2 method, however for my website I think I'll use the javascript method as I don't expect anyone to see the select box unless they have javascript enabled. In fact it's unlikely that anyone will see it at all, as this site is more for me learning web development than a site that lots of people will use.


After that I did some work comparing the speed of different ways of outputting HTML using PHP - breaking out of PHP for HTML, echoing everything or using printf. There didn't seem to be much difference between them, though I think printf is a bit slower (as well as making the code harder to read). Maybe I will post the details of that comparison tomorrow.

After dinner I finished watching National Treasure 2 with Mac and Ben, then watched Lost s02e01 with Mac and Ben, then watched IACGMOOH with Mac. I haven't seen my caterpillar today and he's not in the mud at the side of the tank which I covered up with my trousers last night, so I think he has probably just gone down in the middle of the mud.

The weather this afternoon and this evening was overcast. There was meant to be a crescent moon tonight with the rest of the moon also lit up slightly by reflected light from the earth. Also Jupiter (I think) and Venus are meant to be visible near the moon. Due to the cloud I couldn't see them, though I guess I probably wouldn't have seen them anyway.

Food
Breakfast: Frosties; cup o' tea.
Lunch: 2x cheese on toasts; mandarin; mint kitkat; cup o' tea; Roses.
Dinner: Bacon quiche; baked beans; chips; potatoes. Pudding was: Jamaica ginger cake; tinned mandarin segments; custard. Coffee; Sainsbury's caramel chocolate.

No comments: