In: , , ,
On: 2006 / 05 / 05 Viewed: 82515 times

While playing a bit with Xdebug (a profiling tool for PHP), I've come across something I didn't know and that I frankly found a bit odd : how to use output buffering (PHP function ob_start()) to speed up some stuff.

In a few words, just so you know if this is obvious noob stuff for you and you can skip this article :

PHP:
  1. ob_start();
  2. echo a lot of stuff;
  3. $result = ob_get_contents();

can be a lot faster than a straight

PHP:
  1. $result = a lot of stuff

Say you have a very complex routine that errrr... prints a string with a lot of 'a'.

Straight and simple code would be :

PHP:
  1. $s = '';
  2. for ($i=0; $i <$loops; $i++) $s .= 'a';

Now, with output bufferization you could make it like :

PHP:
  1. $s = '';
  2. ob_start();
  3. for ($i=0; $i <$loops; $i++) echo 'a';
  4. $s = ob_get_contents();
  5. ob_end_clean();

Let's benchmark a bit these two snippets :

PHP:
  1. <?php
  2. $iterations = 50000;
  3.  
  4. function straight($loops = 100) {
  5.     for ($i=0; $i <$loops; $i++) $s .= 'a';
  6.     return $s;
  7. }
  8.  
  9. function buffer($loops = 100) {
  10.     ob_start();
  11.     for ($i=0; $i <$loops; $i++) echo 'a';
  12.     $s = ob_get_contents();
  13.     ob_end_clean();
  14.     return $s;
  15. }
  16.  
  17. $lotsofa1 = straight($iterations);
  18. $lotsofa2 = buffer($iterations);
  19. ?>

Results : on my test machine, straight code took about 60 ms to execute while buffered code took 50 ms. Holy beep, the weirdo syntax is 15% faster !? I guess you save time by manipulating once the result variable, when you get the buffer content, but that was quite surprising for my PHP beginner self.

While I was at it, I pushed it a bit further and tried to think about interesting ways to use this. I thought : maybe it's faster for example to include() a file into a buffer than simply using file_get_content() ?

To test this, I used the following :

PHP:
  1. <?php
  2.  
  3. function bench_readfile($file) {
  4.     ob_start();
  5.     readfile($file);
  6.     $s = ob_get_contents();
  7.     ob_end_clean();
  8.     return $s;
  9. }
  10.  
  11. function bench_filegetcontents($file) {
  12.     return file_get_contents($file);
  13. }
  14.  
  15. function bench_include($file) {
  16.     ob_start();
  17.     include($file);
  18.     $s = ob_get_contents();
  19.     ob_end_clean();
  20.     return $s;
  21. }
  22.  
  23. $content1 = bench_readfile('file1.txt');
  24. $content2 = bench_filegetcontents('file2.txt');
  25. $content3 = bench_include('file3.txt');
  26.  
  27. ?>

Files file1.txt, file2.txt and file3.txt were copies of the same file, but I wanted to be sure that no function would benefit from cached data.

Results : the include() block took 51 ms to execute, readfile() took 7.3 ms and file_get_contents() won it in just 2 ms.

Conclusion : Well, no surprise here. Hopefully built-in function are sometimes optimized enough :Þ

Related posts

Metastuff

This entry "Speeding Things with PHP Output Buffer" was posted on 05/05/2006 at 9:48 pm and is tagged with , , ,
Watch this discussion : Comments RSS 2.0. You can trackback this post from your own site

4 Blablas

  1. 1
    Kates Philippines »
    commented, on 10/May/06 at 10:02 am # :

    Good to know I'm not alone in this profiling and discovering stuff thing in PHP. It's only now that I actually know what ob_start() is for. All the while I thought ob stands for object. Oh, well.

  2. 2
    sanjay shah India »
    wrote, on 19/Jun/06 at 2:11 pm # :

    hi
    Can we pass buffer to the readfile() function
    eg. readfile($buffer) //where $buffer is a output buffer got from

    $buffer=ob_get_contents();

    can it(readfile()) also be used to push contents of buffer to output(brower) any other ...

  3. 3
    eff United States »
    commented, on 23/Jul/07 at 12:02 am # :

    ob_start is great -- it's also a great way to handle exceptions: if something throws an exception while you are filling your buffer, you can print custom error pages, etc.

    thanks for the writeup.

  4. 4
    Andrey Kyrgyzstan »
    commented, on 02/Dec/07 at 7:58 pm # :

    In rare cases it can be very bad, especially with shared hosting with limited RAM given for PHP.
    Also if script crashes somewhere between ob_start and ob_get_contents there won't be any output at all, so user will see blank page.
    but OB still lovely thing :)

Leave a Reply

Comment Guidelines or Die

  • HTML: You can use these tags: <a href=""> <em> <i> <b> <strong> <blockquote>
  • Posting code: Post raw code (no <> &lt; etc) within appropriate tags : [php][/php], [css][/css], [html][/html], [js][/js], [sql][/sql], [xml][/xml], or generic [code][code]
  • Gravatars: Curious about the little images next to each commenter's name ? Go to Gravatar.
  • Spam: Various spam plugins on patrol. I'll put pins in a Voodoo doll if you spam me.
  • I will mark as Spam test comments, all comments with SEO names (ie "My Cool Online Shop" instead of "Joe") or containing forum-like signatures.

Read more ?

 PAPA » 
Close
E-mail It