23

I'm using the JMS Serializer. And I found out that the performance is really bad when I use big data. I've the following object structure displayed as an array:

$jsonData = array(
    'message' => 'this is a nice message', 
    'data' => array(
        0 => array(
          'firstname' => 'achim',
          'lastname' => 'menzel' 
        )
    )
);

This is how I serialize the data:

$serializer = $this->get('serializer');
$encodedJson = $serializer->serialize($jsonData, 'json');

$response = new Response($encodedJson);
$response->headers->set('Content-Type', 'application/json');

Data can be a list of 1 till n objects. When I have more than 500 objects in data, the performance is very very slow (more then 5sec.). When i use json_encode() directly, it tooks not more then 1 second.

How can I improve the usage of JMS Serializer? I don't think that jms serializer cannot handle big data.

This is the main class which will be used for serializing:

class JsonData {

  public $success = false;
  public $message = '';
  public $data;
  public $responseCode = 200;
  public $contentType = 'application/json';
}

And currently this object is inside $data:

class GuestDTO {

  private $userid;
  private $firstname;
  private $lastname;
  private $birthday;
  private $picturemedium;
  private $picturelarge;
  private $gender;
  private $modifydate;
  private $entries = array(); 
}

And $entries is a list of objects from this class:

class GuestlistentryDTO extends AbstractGuestDTO{

  private $guestlistentryid;
  private $guestlistid;
  private $arrivedat;
  private $bouncername;
  private $rejectionreason;
  private $companioncount;
  private $companioncountcheckin;    
  private $winner;
  private $vip;  
}

Without any annotations because I prepared my dto's for using the data as I need.

Gottlieb Notschnabel
  • 9,408
  • 18
  • 74
  • 116
Wolf-Tech
  • 1,259
  • 3
  • 18
  • 38
  • 2
    Have you tried inspecting which parts of JMSSerializer are slowing down the whole thing with xhprof or xdebug and cachegrind/kcachegrind/webgrind? Do you have antything special included in your serialization with JMS serializer - like filtering values or virtual fields ? – Nicolai Fröhlich May 24 '13 at 11:23
  • I only found out that jms serializer is the part which is slowing down the request. I don't set any settings or annotation because i'm using DTO Objects which have the correct attributes what i need so i don't need to set any settings. – Wolf-Tech May 24 '13 at 11:56
  • can you quickly provide your entity so i could give feedback about the performance impact over here? – Nicolai Fröhlich May 24 '13 at 12:01
  • @nifr i added the classes which will be serialized. – Wolf-Tech May 24 '13 at 13:19
  • 4
    I dont think you will ever be able to achieve the performance of the json_ecode/decode with the JMS serializer for a number of reasons. JMS serializer deals with Objects so inherently it will produce A LOT of garbage for the GC, while the native serializers do it in C on arrays which are very cheap in PHP. If performance is what you need doing serilization/deserialization in PHP WILL BE SLOW. I dont think theres anything that will come even close to the native encoder/decoder unfortunately. – Feras May 23 '14 at 20:51
  • 3
    I just ran into the same issue. Apparently it's not JMS Serializer who is to blame, but Symfony's Serializer component (JMS relies on it). Will investigate further and, if I find a solution, I will post it here. – Radu Murzea Jul 14 '14 at 08:10
  • I don't think the things you're serializing are complex enough to use some sort of "library" to do so. In my personal experience the usual json_encode() works perfectly fine, and as you said yourself it is ridiculously quick. – Crembo Jul 30 '14 at 15:09
  • @RaduMurzea any luck on the investigation? – Dimitry K Aug 19 '14 at 10:38
  • 1
    @DimitryK Not really. We abandoned the idea of using JMS and therefore we didn't pursue the investigation further. Sorry for not providing a more helpful answer... – Radu Murzea Aug 19 '14 at 11:18
  • @RaduMurzea, and which option for serializing did you choose instead? :) – Dimitry K Aug 19 '14 at 12:20
  • @DimitryK Since we needed very few features and wanted maximum customizability, we developed a solution of our own. Also fits much better with the way we want our projects to look like. – Radu Murzea Aug 19 '14 at 13:20
  • @RaduMurzea which solution did you choose? – cirpo Aug 22 '14 at 12:32
  • @cirpo See the comment above: we developed a solution of our own because we only needed a very small subset of the features. – Radu Murzea Aug 22 '14 at 12:45
  • 2
    Another great option is Fractal http://fractal.thephpleague.com/ – softius Oct 14 '14 at 15:49
  • @softius this fractal seems promising (though from quick glance at docs seems less powerful and not supporting annotations as JMS Serializer does). Any feedback on using in in real life? – Dimitry K Nov 22 '14 at 21:24

3 Answers3

2

Unfortunately this library is inherently pretty slow. There's a lot of recursion in there.

A couple of things you can do however is query cache everything using either Redis or Memcache. You can also be smart with your SQL queries, try to trim the fat. Only give the serializer the important data you need so it isn't trawling through lots of data that won't be getting used anyway.

Ewan Valentine
  • 3,741
  • 7
  • 43
  • 68
1

Are you using partial responses? your problem seems actually quite obvious. In my opinion your client should ask for a limited number of items and ask for more when necessary...

David Vartanian
  • 460
  • 4
  • 12
1

I've hit the same issue too and the "best workaround" has been to create a cache for the generated json output in Redis and plug CRUD Doctrine events on specific entities to flush the cache.

Some help came from fine tuned mix of groups and inclusion/exclusion rules for referenced collections

lcapra
  • 1,420
  • 16
  • 18