PHP's ob_start() pre-allocates 40k memory per call
ilia.ws
ilia.ws
http://svn.php.net/viewvc/php/php-src/trunk/main/output.c?vi...
http://svn.php.net/viewvc/php/php-src/trunk/main/php_output....
#define PHP_OUTPUT_HANDLER_DEFAULT_SIZE 0x4000- if you have to use it, you need to question yourself carefully as to "why" and if there is a better way.
The better question might be "if you want to turn it off, the question is why", or something.
ob_start();
include $file;
$contents = ob_get_contents();
ob_end_clean();I'd assume the 16x calls would be because they have a very complicated set of templates/layouts/partials, all doing their own templating.
I can see 16 calls over the lifetime of the request, but what was confusing me was how they could have 16 nested calls forming some ob_start();ob_start();...ob_end_flush(); Maybe some crazy way to avoid having to return text up the tree through function returns. But I read the post again and it said nothing about nesting them, so it's probably just something like 16 sub-templates or whatever as you suggest being processed at different intervals, not necessarily nested, with the gc not collecting frequently enough.
PHP is written in C which is not garbage collected.
PHP itself collects garbage, but this buffer is an internal C buffer and would be released immediately.
Oh Steve Souders, your quest for speed will doom us all:)
What's the best PHP framework/library for that kind of thing?
They call it `PHP'.
The basic problem you run into is that PHP is basically a templating language at its heart. If you don't immediately open with a "<?" you start sending data. If you want to use PHP as it was originally intended -- as raw HTML with a smattering of dynamic bits in the middle -- without losing the ability to set headers, then ob_start makes sense. If on the other hand you want to use it in the way that most people do, you open with "<?php" and proceed to abuse a whole bunch of bastardized perl templating functions followed by an "echo $data; ?>" at the end of your source code.
Now, given that PHP as a templating language is basically terrible, it's not that far out to just say, "To hell with PHP's native templating features, we're going to use our own!" but at that point you are already pretty far gone.
If data sent over packet network wasn't bufferend, most of the time partial frames would be sent. With buffering, the OS usually sends full frames, making better use of bandwidth, at slight expense of delay and tiny extra memory use. There is even some tunable smarts built-in to keep delay down to manageable size.
The OS tries to create full frames from partial writes from applications. If OS didn't provide that service, it would be up to application to align write size for optimal bandwidth utilization.
You don't really want PHP developers to have to think about size of strings they output, now do you? ;-) For reference, http://www.pbm.com/~lindahl/mel.html -- a guy that hand-picked intervals between instructions in drum memory for better performance -- not exactly the kind of work for typical webdeveloper.
This is one reason why the C++ cognoscenti recommend using std::deque as your default array-like container rather than std::vector.
I haven't looked at PHP's implementation, and I've long since learned not to expect intelligent, rational implementation decisions from that language community, but it's certainly possible to grow by a fixed amount and remain O(N) by never copying elements at all.