Why does Symfony2 spend 70-90% of its time analyzing YAML?

As shown in Webgrind's output below, my application spends most of its processing time parsing YAML.

Webgrind Output - 83.63 percent YAML parsing.

Note. Webgrind output is in percent. Thus, the addition of โ€œTotal Self Costโ€ shows that 83.63 percent of the total time spent processing YAML.

I saw this related thread:

Applications for Symfony2 YML applications for each request

However, my implementation uses the ApcClassLoader class, as shown below:

$loader = new ApcClassLoader('odr_dev', $loader); $loader->register(true); 

Also, I checked the APC system using apc.php, and my classes and pages are in the APC cache and hit. This happens on PROD or DEV by any request, even after the caches are full.

My theory is that we have a circular reference to the entity, and the system cannot successfully parse the YAML to cache it. Thus, he tries to parse YAML for each request.

However, I do not see any errors in the fact that I can not parse YAML or something in the logs and I do not know how to determine if this could be in this case or where to look further.

+6
source share
2 answers

After going through each line of code involved in this process, I found that Doctrine uses the default cache, which is only valid for loading a single page.

I think that I and many others have suggested that when we enable APC, it will also be used by Doctrine to cache metadata. In fact, Doctrine by default uses its array cache, unless otherwise specified.

This page lists Doctrine configuration options:

http://symfony.com/doc/2.3/reference/configuration/doctrine.html

After adding caching options to my /app/config/config.yml as shown below:

 doctrine: dbal: driver: %database_driver% host: %database_host% port: %database_port% dbname: %database_name% user: %database_user% password: %database_password% charset: UTF8 orm: auto_generate_proxy_classes: %kernel.debug% auto_mapping: true result_cache_driver: type: memcached host: 127.0.0.1 port: 11211 instance_class: Memcached metadata_cache_driver: type: memcached host: 127.0.0.1 port: 11211 instance_class: Memcached query_cache_driver: type: memcached host: 127.0.0.1 port: 11211 instance_class: Memcached 

After correction on the same page there is no interaction with the YAML parser and loads in 302 ms against 5851 ms for a general acceleration of 19X. In addition, the cachegrind file went from 121 MB to 3.4 MB, and these results are generally consistent with a number of samples.

Here is the same Webgrind showing the difference:

Webgrind fixed

So basically it was a configuration issue. From what I saw in StackOverflow questions and other forums, it seems like it turns off here about how caching works. Essentially, you need to explicitly enable it for Doctrine caching, as described above, or use an almost useless default value.

Symfony2 can sometimes be too "customizable", and this is one example where it never occurred to me that it would be separately configured. In this regard, this is a powerful feature (the ability to use separate caches for things), but until you understand this, the system is completely compromised in speed.

+1
source

I think your problem is probably the recursive YAML resources (or the like). You see 4000 + a call to Yaml\Parser::parse . When checking my own application (which is rather complicated) when loading a page with a completely empty cache, I see only 166 requests. And it drops to 2 calls to load pages using the warm cache.

I do not think that your use of the class loader cache may affect the YAML parsing, as you have discovered. I suspect the ticket you are referring to is probably wrong)

+1
source

Source: https://habr.com/ru/post/972190/


All Articles