Your test is flawed –
- network performance can skew the numbers either direction +/- 50% or more. Turn on buffering at the start to eliminate this.
ob_start();
-
you don’t account for timer granularity – which for most systems running php is 18.2ms… so you should be testing for the timer rollover before starting your test.
-
testing for a number of iterations with inaccurate (VERY inaccurate) timers is usually a bad idea – it’s better to test for a fixed period of time as the only place you can trust the time is at the rollover.
/* wait for tick change to reduce granularity bug */
$errorOffset=microtime(true);
while ($errorOffset==microtime(true)) {}
$finish=microtime(true)+3;
I’d then advise running the test for three seconds, which should on a reasonably fast server deliver around 300-500K iterations to compare against.
- The size of the buffer could also be interfering, and outputting enough iterations for any sort of test to matter would be MEGABYTES worth of data – so use
ob_clean();
after each test to clear out the buffer
- Are you running those back to back as a single file? code caching could be interfering making whichever one is second run faster… so make sure that’s two separate tests.
These are common enough mistakes when it comes to benchmarking PHP though. It’s not like the majority of PHP developers even learned about timer granularity.
If I were to test, it would go like this:
<?php
$variable1='1';
$variable2='2';
$variable3='3';
$variable4='4';
$variable5='5';
ob_start(); // remove network output from interfering with test
$count=0;
/* wait for tick rollover to reduce granularity bug */
$errorOffset=microtime(true);
while ($errorOffset==microtime(true)) {}
$finish=microtime(true)+3;
?>
<?php while (microtime(true)<$finish): ?>
<tr>
<th><?php echo $variable1; ?></th>
<td><?php echo $variable2; ?></td>
<td><?php echo $variable3; ?></td>
<td><?php echo $variable4; ?></td>
<td><?php echo $variable5; ?></td>
</tr>
<?php $count++; ?>
<?php endwhile ?>
<?php
ob_clean();
echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html
xmlns="http://www.w3.org/1999/xhtml"
lang="en"
xml:lang="en"
><head>
<meta
http-equiv="Content-Type"
content="text/html; charset=utf-8"
/>
<meta
http-equiv="Content-Language"
content="en"
/>
<title>
Echo vs. Opening and Closing PHP benchmark
</title>
</head><body>
<p>
Iterations using <?php ?> : ',$count,'
</p>
</body></html>';
?>
and
<?php
$variable1='1';
$variable2='2';
$variable3='3';
$variable4='4';
$variable5='5';
ob_start(); // remove network output from interfering with test
$count=0;
/* wait for tick rollover to reduce granularity bug */
$errorOffset=microtime(true);
while ($errorOffset==microtime(true)) {}
$finish=microtime(true)+3;
while (microtime(true)<$finish) {
echo '
<tr>
<th>',$variable1,'</th>
<td>',$variable2,'</td>
<td>',$variable3,'</td>
<td>',$variable4,'</td>
<td>',$variable5,'</td>
</tr>';
$count++;
}
ob_clean();
echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html
xmlns="http://www.w3.org/1999/xhtml"
lang="en"
xml:lang="en"
><head>
<meta
http-equiv="Content-Type"
content="text/html; charset=utf-8"
/>
<meta
http-equiv="Content-Language"
content="en"
/>
<title>
Echo vs. Opening and Closing PHP benchmark
</title>
</head><body>
<p>
Iterations using Echo : ',$count,'
</p>
</body></html>';
?>
After summing the results of 20 tests (which the results still fluctuate by 5% – probably due to server load) the average for <?php ?> was 591,362 and for echo without opening and closing php it came to 647,953. That’s almost 10% difference. 10% is pretty damned good especially since it’s cleaner code.
I mean, this fistfull of ugly:
<?php while (microtime(true)<$finish): ?>
<tr>
<th><?php echo $variable1; ?></th>
<td><?php echo $variable2; ?></td>
<td><?php echo $variable3; ?></td>
<td><?php echo $variable4; ?></td>
<td><?php echo $variable5; ?></td>
</tr>
<?php $count++; ?>
<?php endwhile ?>
vs.
while (microtime(true)<$finish) {
echo '
<tr>
<th>',$variable1,'</th>
<td>',$variable2,'</td>
<td>',$variable3,'</td>
<td>',$variable4,'</td>
<td>',$variable5,'</td>
</tr>';
$count++;
}
Shouldn’t even be a choice on cleanliness ALONE. Oh, and string addition using periods is slower than comma’s… don’t waste time having to build the full string in memory on top of the copy in the bytecode, when you can just dump the bytecoded copy at it. String addition should be reserved for when it’s NEEDED – like inside an inline evaluation. That’s why echo accepts comma delimited values in the first place.
But again, that’s where understanding how things work under the hood helps… I really think people should be forced to learn ASM before being allowed anywhere NEAR a high level language… and after 30 years of programming, MOST of the PHP code I look at just has me shaking my head going “don’t they teach these kids ANYTHING?”