jms serializer performance issue
Asked Answered
D

3

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.

Draftee answered 24/5, 2013 at 10:59 Comment(15)
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 ?Chapeau
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.Draftee
can you quickly provide your entity so i could give feedback about the performance impact over here?Chapeau
@nifr i added the classes which will be serialized.Draftee
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.Solvable
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.Clockwise
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.Chuckle
@RaduMurzea any luck on the investigation?Conjugated
@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...Clockwise
@RaduMurzea, and which option for serializing did you choose instead? :)Conjugated
@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.Clockwise
@RaduMurzea which solution did you choose?Gregarine
@Gregarine See the comment above: we developed a solution of our own because we only needed a very small subset of the features.Clockwise
Another great option is Fractal fractal.thephpleague.comStaffer
@Staffer 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?Conjugated
R
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.

Rivy answered 19/1, 2015 at 12:4 Comment(0)
K
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...

Kutchins answered 11/3, 2015 at 0:27 Comment(0)
S
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

Sycophancy answered 19/4, 2015 at 17:32 Comment(1)
How do you cache your JSON outputs? How can you force it?Peduncle

© 2022 - 2024 — McMap. All rights reserved.