Posts tagged with ‘Profile’

0

PHP Output Profiling: Echo vs Concat

I was recently reviewing some code when a simple question came up…

What’s the fastest way to output a segmented string?

1
2
3
4
5
echo '<div>';
echo '<span>';
echo 'This is a random number: ' . mt_rand(1,100);
echo '</span>';
echo '</div>';

– OR –

1
2
3
4
5
6
7
$html = '';
$html .= '<div>';
$html .= '<span>';
$html .= 'This is a random number: ' . mt_rand(1,100);
$html .= '</span>';
$html .= '</div>';
echo $html;

My initial guess was that calling echo as little as possible during a request would end up performing better as there would be no need to interact with an output buffer or perform other logic tied to STDOUT.

I ended up asking a few friends and colleges what they thought about the question and most responded with “hu?” After telling them that I was in fact serious the majority of their opinions fell on echo being the winner. Still, others thought of ways to get a segmented string out faster, like pushing them onto an array and executing echo implode(”, $array);

This difference of opinion got me thinking about what was truly the most efficient way to output a collection of strings? Curiosity got the best of me and I quickly setup some profiling tests using my Bench Class to find out the answer.

Profiling Setup

I used the following code in order to get enough data points for a solid performance comparison.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$samples = 40;
$sets = array(10,20,50,100,500,1000,1500,2000,2500,3000);
$results = array();
foreach($sets as $iterations) {
  $results[$iterations] = array();
  for($i=0; $i<$samples; $i++) {
    Bench::start();
    for($j=0;$j<$iterations;$j++) {
      // ... Output Test ...
    }
    $results[$iterations][] = Bench::stop();
    Bench::reset();
  }
}

Tests

I tested the performance on four different methods of outputting data…

(more…)

2

Benchmarking and Timing PHP Class

Introducing a simple, yet deceivingly useful, micro benchmarking / timer class called Bench.

I’ve found myself on more than a few occasion using this familiar block of code in order to quickly narrow down a bottleneck or test a specific section of code.

1
2
3
4
$start = microtime(true);
// [Some Code To Test]
$time = (microtime(true) - $start);
echo $time.' Seconds';

This is a crude but effective way of finding out how long it takes to get from line A to line B. On the down-side, this technique is annoying to implement, only measures time between two points, and makes code look very cluttered — so I started developing Bench.

Features

Bench offers more than just clean looking code or timing between two lines. Its goal is to be more powerful and reusable than simple Microtime Arithmetic while trying avoid stepping on anyone’s toes (*cough* *cough* Xdebug, see below).

Start and Stop

Bench can perform the same operation as the example above but in a much cleaner manner.

1
2
3
Bench::start();
// [Some Code To Test]
echo Bench::stop() . ' Seconds.';

Marks

“Marks” are simply points in code that one would like tracked by Bench. They are easy to use, quick to implement, and very useful when tracking multiple parts of a script/request.

1
2
3
4
5
6
7
8
9
Bench::start();
// [Application Bootstrap]
Bench::mark('bootstrap');
// [Database Connection Opened]
Bench::mark('database');
// [Data Processing + Manipulation]
Bench::mark('processing');
// [HTML Creation]
Bench::mark('html');

Each call to mark() creates a Mark Array that contains the id, microtime of when it occurred, seconds since start, and seconds since the previously called mark.

(more…)