Why does constructing a Symfony Response take so long, use so much memory, and what can I do about it?

392 Views Asked by At

Test script:

#!/usr/bin/php
<?php
require __DIR__.'/../www/autoload.php';

$start = microtime(true);
$mem = memory_get_usage(true);
$resp = new \Symfony\Component\HttpFoundation\Response();
$elapsed = (microtime(true)-$start)*1000;
$used_mem = memory_get_usage(true)-$mem;
echo number_format($elapsed,2)." ms\n";
echo number_format($used_mem/1024,1)." KiB\n";

Output:

2.25 ms
256.0 KiB

The funny thing is, if I put it in a loop, the cost doesn't increase much:

$resp = [];
for($i=0; $i<100; ++$i) {
    $resp[] = new \Symfony\Component\HttpFoundation\Response();
}

6.73 ms
512.0 KiB

But I only need one response, so that doesn't particularly matter.

Looking at the constructor for Response, it barely does anything. It just initializes a handful of variables.

2ms is a significant portion of my response time, I'd really like to get that down if possible.

1

There are 1 best solutions below

1
On BEST ANSWER

When you have this kind of issues you should usually profile using XDebug: http://www.xdebug.org/docs/profiler

It will tell you exactly where the "problem" lies by showing you how much time was spent in each method and how many times it was called.

In this case, the "problem" is Line 206, construction of \DateTime object, and afterwards \DateTimeZone object.

To eliminate all other factors, make sure no autoloading occurs first, so modify your test to:

<?php

require 'vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Response.php';
require 'vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/HeaderBag.php';
require 'vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/ResponseHeaderBag.php';

$start = microtime(true);
$mem = memory_get_usage(true);
$resp = new \Symfony\Component\HttpFoundation\Response();
$elapsed = (microtime(true)-$start)*1000;
$used_mem = memory_get_usage(true)-$mem;
echo number_format($elapsed,2)." ms\n";
echo number_format($used_mem/1024,1)." KiB\n";

Test with Line 206 on my machine

3.57 ms
0.0 KiB

Test with Line 206 commented out on my machine

0.32 ms
0.0 KiB