Checking the performance reading arrays with PHP


Reading last Fabien Potencier’s post I see something interesting: “People like micro-optimizations. They are easy to understand, easy to apply… and useless“. It’s true. We don’t need to obsess with small micro-optimizations. As someone said in a comment “developer time is more precious than processor time“. It’s true again. But normally our code is coded once and executed thousands of times, and we must keep in mind that CPU time many times means money. We need to balance it (as always). But, WTH. I like micro-optimizations, and here comes another one: Checking the access to arrays with PHP.

$limit = 1000000;
$randomKey = rand(0, $limit);

// we create a huge array
$arr = array();
for($i=0; $i<=$limit; $i++) {
    $arr[$i] = $i;
}

error_reporting(-1);
$time = microtime(TRUE);
$mem = memory_get_usage();

$value = $arr[$randomKey];
for($i=0; $i<=$limit; $i++) {
    echo $value;
}

print_r(array('memory' => (memory_get_usage() - $mem) / (1024 * 1024), 'microtime' => microtime(TRUE) - $time));

with this first example we will loop over a big for statement and we are going to retrieve the value of an array.

[memory] => 5.6837158203125 [microtime] => 0.32066202163696

Now we’re going to do the same, but getting the value of the array inside the loop:

for($i=0; $i<=$limit; $i++) {
    $value = $arr[$randomKey];
    echo $value;
}

[memory] => 5.6837158203125 [microtime] => 0.35844492912292

and now without creatin the extra variable $value

for($i=0; $i<=$limit; $i++) {
    echo $arr[$randomKey];
}

[memory] => 5.683666229248 [microtime] => 0.35710000991821

Conclusion

As we can see the memory usage is almost the same, and the time is almost the same too. Obviously fetching the value of the array outside the loop is faster than doing inside the loop. But we must take into account that we’re working with big arrays. With small ones those times are very similar. This time we don’t have any significant outcome. Both methods have the same behaviour. Maybe it can be obvious, but I wanted to check it out.

About these ads

About Gonzalo Ayuso

Web Architect specialized in Open Source technologies. PHP, Python, JQuery, Dojo, PostgreSQL, CouchDB and node.js but always learning.

Posted on August 15, 2011, in micro-optimizations, php, Technology and tagged , , . Bookmark the permalink. 8 Comments.

  1. You’re actually testing different things:

    $value = $arr[$randomKey];
    for($i=0; $i one lookup, one assigment, $limit echo’s

    for($i=0; $i $limit lookups, $limit assignments, $limit echo’s

    for($i=0; $i $limit lookups, $limit echo’s

    hence that the numbers differ (in somewhat logical order, most actions to least actions = longest to shortest, no assignment = less memory usage) makes sense I guess.
    I would also recommend running each test *at least* a 1000 times and taking the average in order to make sure that variance is being leveled out.

    • meh, editor screws up the code examples.

      First code: one lookup, one assigment, $limit echo’s
      2nd code: $limit lookups, $limit assignments, $limit echo’s
      3rd code:$limit lookups, (no assignments), $limit echo’s

  2. I don’t think the tests make sense to the conclusion. In the first test you lookup the array once and then do $limit times of echo while in the other two tests you lookup $limit times and echo $limit times.

  3. OK. Let me explain a little bit the objective of the performance test. I think there is a little misunderstanding. Basically I want to check the performance reading from an array one value once, and thousand of times within a loop. When we want to find bottlenecks in our applications loops usualy are the main source of problems. Maybe the correct way to check what I want to check is inspecting the C code of PHP, but it’s hard for me :). Because of that I have done it with timers and memory usage.

    Normally I need to read values from arrays. I had the idea that is better to extract the value in a variable instead of reading directly from the array (if we need to perform the operation over a loop), but I wasn’t not sure. Problably it was a PHP’s urban legend such as the performace of single quotes and doubles quotes in strings. Because of that I’ve done this test. Maybe the title of the post is not perfect, but I did’t find any other better (at least whitout using a three lines title ;))

    I didn’t performed the test changing the $limit variable because the outcomes wasn’t significant (I did, indeed, but no published in the post). Bigger $limit, bigger differences. The idea was compare the performace in a single read and over a huge array to see if it necesary to try to put the reads of the array outside the loop when coding applications, or not paying attention to this issue because the benefits are insignificant.

    OK the perfect test will be done running the test several times and taking the average. More or less I’ve done it, but I see there aren’t big differences. (memory usage is obviously the same always). Problably would be better to do it over different cores (64 bits, 32 bits, …). But as I said before my aim wasn’t to create an perfect test. The aim was to clarify myself in one punctual operation that I use in my dayly work, and share the outcomes

  4. Hi Gonzalo,

    what you are measuring here is the performance of echo, not the performance of the array access. You should try to add ob_start() and ob_end_clean() to remove the performance drop of outputting things. Or you change the echo to an assignment, for example instead of
    echo $value;
    you can try
    $a = $value;
    That much faster than echoing something and maybe gives better results for your question.

    Here are my results, with ob_start() before and ob_end_clean() after the loop:

    [memory] => 0.00012969970703125
    [microtime] => 0.58387804031372

    [memory] => 0.00012969970703125
    [microtime] => 0.78218603134155

    [memory] => 7.62939453125E-5
    [microtime] => 0.63797211647034

    And here with an assignment instead of echo:

    [memory] => 0.00017547607421875
    [microtime] => 0.31222891807556

    [memory] => 0.00017547607421875
    [microtime] => 0.49804091453552

    [memory] => 0.0001220703125
    [microtime] => 0.36840891838074

  5. wow this was a waste of my developer time

  1. Pingback: Performance des tableaux

  2. Pingback: Checking the performance reading arrays with PHP « Gonzalo Ayuso … | Linux Blog

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 1,003 other followers

%d bloggers like this: