Deprecated: preg_replace(): The /e modifier is deprecated, use preg_replace_callback instead in /share/CACHEDEV1_DATA/Web/www/libraries/UBBcode/text_parser.class.php on line 228
Micro-optimizations: when to define a variable in PHP?

Comments Blog About Development Research Sites

Micro-optimizations
When to define a variable in PHP?

Jul 1, 2011
Some time ago I wrote about optimization in PHP and MySQL. One of the underlying ideas was that optimizing is a problem of finding bottlenecks: which part of an application is slowest, or has the largest oppertunity for speedup? In short, where is the most to gain?

Sometimes, however, it is fun to just look at the smallest possible difference. The micro-optimiziations, the little changes that will not be noticed by anyone, ever. One of these is the question whether or not to pre-allocate a variable before using it. Now, for certain situations it is most definitely faster to pre-allocate: when you need to incrementally use more memory, reserving it in one big block is quite a bit better than adding a tiny new block repeatedly. We see this in Matlab for example, where reserving an entire array beforehand is better than increasing the arraysize during iteration. This page explains it in great detail, as it is an important trick to keep up your sleeve when writing resource-intensive mathematical simulations.

But let us look at an even more trivial scenario: do you define a variable before you use it in a loop, or only when you actually assign data to it? Consider the following two functions:
Code (php) (nieuw venster):
1
2
3
4
5
6
7
8
9
10
11
12
// Preallocate a variable, then use it.
function preAllocate () {
  $a = 0;
  for (
$i = 0; $i < 1000000; $i++)
    $a = $i;
}


// Allocate a variable when you use it.
function inlineAllocate () {
  for (
$i = 0; $i < 1000000; $i++)
    $a = $i;
}

These functions do effectively the same (well, nothing really): they just assign an (increasing) value to a variable $a. In one scenario the variable exists before the loop, in the other scenario it does not. Due to PHP's scoping rules, the variable also exists outside the loop in both scenario's, unlike in some stricter languages. But which is better? You might think that pre-allocating also helps in this case: the variable does not have to be instantiated every time a value is assigned to it, and perhaps it does in the second case. However the second case is arguably simpler, and it uses less instructions so possibly it is faster instead?

To test this out, I first ran both functions a single time (in one script). The results were surprising: on my server, with PHP 5.3.6 (as Apache module under Windows), preAllocate() was about 40% faster than inlineAllocate. Since I did not expect any difference, this came as somewhat of a shock. So I wrote a script to run each function a 100 times (alternating between both functions) and output the result, as well as the average. The results were interesting:

One-Sample Statistics
 NMeanStd. DeviationStd. Error Mean
preAllocation100.105863683223725.003474814405701.000347481440570
inlineAllocation100.105696327686310.004060833233632.000406083323363


Or to put this in a nice graphic, courtesy of SPSS:

Difference between inline- and preallocating variables.

Short summary: there is no detectable difference at all. Both scenario's are exactly the same, performance-wise. So where did my initial result come from? As a rule, when you cannot explain your data, the first thing you should do is simply look at your data. Check out the first few runs:

inlineAllocate()preAllocate()
0.140207052230830.10696196556091
0.105957031250.1058361530304
0.105367898941040.10418486595154
0.105640888214110.10547494888306
0.105654954910280.10153698921204
0.106487989425660.10285401344299


Notice the odd one out? That's right: the very first call is much slower than the rest. For some reason, the first function to be called in a PHP application needs a bit of startup time, after which it will run smoothly ever since. Switching the functions around so the inline allocation scenario runs first shows the exact same slowdown for that first call.

So there you have it: if you need a temporary variable inside a loop, do not bother to preallocate it, at least not for performance reasons, since it does not make one iota of a difference.

FragFrog out!

New comment

Your name:
Comment: