5

I generate dynamically graphic in my controller:

  1. if not file exists (unique filename) then generate graphic and save it

  2. return RedirectResponse($url)

(3. I've tried also:

    $fp = fopen($url, "rb");
    $str = stream_get_contents($fp);
    fclose($fp);

    $response = new Response($str, 200);
    $response->headers->set('Content-Type', 'image/png');
    return $response;

)

I need it to generate dynamically userbars for users [on this graphic some text will be automatically updating if some changes will be done on my websites].

So it's important for me that this script works fast and doesn't kill my server/bandwitch. To achieve that I've made cache where all generated graphics are stored. But i've got a problem with speed, solutions which i've described above are pretty slow, when i've tested it in chrome with developer tool (F12) then it shows me that both solution (2. and 3.) takes about ~1s (when the same graphics [without controllers etc. just direct url to .png] loads 44ms).

So if only for me it takes about ~1s per graphic then if for example 1000 users will generate at the same time this graphic it can slower my website I think.

Please help, do you know any faster ways to do that?

PS. Redirect isn't most desire thing for me, because I would prefer to leave url as it is, for example smth/username/userbar/ insted of smth/img/userbars/cache/blabla.png. But if it will be much faster then I can stand it :).

EDIT: To be clear: I'm not looking for solution to cache images, my problem is that returning images via controller (already generated images, just from ftp) takes about 1s, when normally if you do for example

           <img src="direct_url_to_png"> 

it takes about 44ms.

Wojciech Kulik
  • 7,823
  • 6
  • 41
  • 67

1 Answers1

3

You can use Varnish to cache the images, Varnish is a HTTP proxy that sits in front of the webserver. It takes some time & knowledge to configure it, but it is a very good piece of software.

Alternatively, you may cache the images in memory using shared memory, memcache, or redis. This would probably be less effectly than Varnish, but it would save the filesystem IO.

You should test where the most time is spent, I expect it's a combination of file I/O and PHP parsing time, but as we saying in Dutch, "Measuring is knowing" ;)

Here's a simple example which should give you the general idea on how to do that:

<?php
class MyClass
{
  function __construct()
  {
     $this->timer = array(
       'start' => microtime(True);
     );
   }

  function myAction()
  {
    $this->timer['startaction'] = microtime(True);

    $fp = fopen($url, "rb");
    $this->timer['startstream'] = microtime(True);
    $str = stream_get_contents($fp);
    fclose($fp);
    $this->timer['endstream'] = microtime(True);

    $response = new Response($str, 200);
    $response->headers->set('Content-Type', 'image/png');

    $this->timer['endaction'] = microtime(True);
    print_r($this->timer)
    return $response;
  }
}

Another thing that may be an option is to use HTML/CSS to show the graphs. This may or may not work depending in what your graphs look like but I've used this in the past and it worked quite well.

Martin Tournoij
  • 26,737
  • 24
  • 105
  • 146
  • "is to use HTML/CSS to show the graphs" what do you mean? I don't see it because I need first to get some statistics from database, so I would prefere to pass it by Controller. I think that a problem is in returning this image (using stream_get_contents or redirection which takes about 800ms). By the way, maybe I'm totaly wrong and my solution isn't so bad? If it only affects on loading image for user and it won't slow down server than I think it could be as it is? As I see you focused on storing generated images, but a real problem is in returning this image :). – Wojciech Kulik Feb 05 '12 at 13:26
  • This times which I've written down above refers to loading images from cache. Load already generated image from ftp via controller takes about 1s and I would like to improve it. – Wojciech Kulik Feb 05 '12 at 13:33
  • Thanks for advice, i've tested it and generally it isn't so bad. When I generated graphic separately then it loads only about 150ms (doesn't matter if by redirect or stream_get_contents) so it's not so bad i think. Loading it directly takes about 32ms, but I check if file exists, get information from database and get graphic, so it seems to be good. – Wojciech Kulik Feb 05 '12 at 14:01