I am writing an application in PHP, and I decided to do some testing on my own to determine how well PHP handles buffers and buffering. Specifically, I wanted to see if manually calling ob_start() and ob_flush() would have a huge effect on my program.
I conjured up 10KB of lorem ipsum and went to work. I put a timer in PHP at the start and end of a for loop that writes the 10KB of lipsum (in display:none div blocks) 100 times, for a total of 1MB of data, which I figured would be enough work that random CPU load wouldn’t throw off my data too much.
Besides the PHP timer, I popped open Chrome’s developer tools (F12) and recorded the “time” and “latency” field. If I have my terminology correct, the “time” is the total amount of time the page took to respond, and render, and “latency” is just the time until the page first received data from the server.
So here’s the mystery: When I do nothing but write the 10KB of lipsum 100x, my averages are:
PHP Time: 0.00630ms
Chrome Time: 565.6ms
Chrome Latency: 28.3ms
When I call ob_start() at the very beginning, and ob_flush() at the very end:
PHP Time: 0.00792ms
Chrome Time: 540ms
Chrome Latency: 33ms
HOWEVER, and here’s the mystery – when I call ob_start() and ob_flush() at the beginning and end of each 10KB block of text, my Chrome-reported latency spikes by 4x.
PHP Time: 0.005814ms
Chrome Time: 624.7ms
Chrome Latency: 134.9ms ???
As far as I know, the chrome latency should be cut by 100x, since I’m flushing the buffer 1/100 of the way through the PHP output. I know that the ob_start() and ob_flush() operate on a higher buffer, and they actually flush into a lower buffer, I would expect that lower buffer to flush at the same intervals, meaning I would see about the same latency.
My test rig is a very modest Intel ATOM netbook with Nvidia ION graphics, Windows 7 home premium (32-bit) and WAMPserver running Apache 2.2.22 with pretty much default settings. I used Chrome 24.0.1312.52 m. CPU load was moderate but not 100% during the tests, and my ram was nowhere near full.
Test Code:
http://pastebin.com/zf62Y4yz
Thanks!
ob_flushsends the content out to the client. By letting PHP determine when this is or doing all at once with a singleob_flush, it can batch the send inside http message efficiently. When you manually break it up at an arbitraty points, in this case every 10K you are breaking and enforcing at least one manual package transmit. The latency of this transport to the client is probably higher than the actually php buffer flushing.