-
Notifications
You must be signed in to change notification settings - Fork 152
Emitter performance #238
Comments
I can't reply for the different emitter implementations, but for these particular bit:
This is a good use-case scenario for a middleware, in my opinion (strip body completely, replace with empty body, make sure header is well-formed, yadda yadda). |
There are. As you noted, the
Honestly, you'll likely need to benchmark in your own environment with typical payloads to see which is a better fit for your needs.
Yes, IF the underlying
The emitter is called by some process in your application; it doesn't wrap execution (at least, that was never the intent). In the case of Expressive, for instance, The reason it interacts with the output buffer is... well, we have to get the content back to the client somehow, and the way PHP does that is through the output buffer. If you're working in an async environment, I assume you'd need a custom emitter that is capable of writing back on the socket in which the request was transmitted.
As @Ocramius has noted, I think those particular items would make great middleware. |
Okay, so I benchmarked this: <?php
header("Content-Type: image/jpeg");
while (ob_get_level() > 0) {
ob_end_clean();
}
fpassthru(fopen(__DIR__ . "/image.jpg", "rb")); Versus this: <?php
use Zend\Diactoros\Response\SapiStreamEmitter;
use Zend\Diactoros\Stream;
require __DIR__ . '/vendor/autoload.php';
$body = new Stream(__DIR__ . '/image.jpg');
$response = new Zend\Diactoros\Response($body);
$response = $response
->withHeader("Content-Type", "image/jpeg");
$emitter = new SapiStreamEmitter();
$emitter->emit($response); Versus the same Results look, well, not so good for PHP, which adds around 100% overhead, so ~40 msec for Results look good for Diactoros, though - it adds only a ~0.25% overhead per request, about ~41 msec. So the performance of Diactoros looks good! So I'm closing this issue. I still plan on benchmarking against appserver.io and php-pm for comparison - let me know if you'd like me to post the results? |
I'm about to start using Diactoros to process many image requests (profile photos that are only accessible to members) and have some concerns regarding performance.
I generally try to avoid dispatching PHP when delivering high volumes of assets, e.g. using a caching strategy where PHP is invoked only the first time an image is requested - for subsequent requests, the physical asset with the requested URL will be in place, and the server will serve it up without hitting PHP.
In this particular case, the images have to be protected from public access, so there's no way around hitting PHP for every image.
First, a question: how come there are two emitter implementations? Why do we have
SapiEmitter
as well asSapiStreamEmitter
? Are there performance differences? I don't see a benchmark in the package, so it's hard to tell.I can tell at least that
SapiStreamEmitter
appears to support partial (resume) requests. Another difference appears to be thatSapiEmitter
echoes the entire body directly to the output buffer, whereasStreamSapiEmitter
echoes the body in chunks. The manual currently states that only "A single implementation is currently available", so not much help there, and there are no class-level doc-blocks describing the purpose of each implementation.Isn't it generally more efficient to
fopen('php://output')
and thenstream_copy_to_stream()
from one stream to the other, avoiding output buffer overhead etc.?Is there any use-case for an emitter that supports output buffering at all? I mean, the whole purpose of PSR-7 is to model the response, such that there is (theoretically) no missing information still needing to be computed by the time we've populated the response and are ready to emit, so when is output buffering useful? Why isn't it being suppressed by the emitter?
And finally, what do you think about adding support for
X-Sendfile
under Apache andX-Accel
under NGINX? Is it something emitters could cover, or is it out of scope?I know that's a lot of questions, but I'm trying to assess whether the simple strategy of emitting protected assets is (or can be made) feasible in the first place, if I can help in any way, or if I need to think about alternate strategies.
The text was updated successfully, but these errors were encountered: