为什么Symfony2应用程序花费70-90%的时间来解析YAML?

时间:2014-07-14 17:56:50

标签: php symfony doctrine-orm yaml

如下面的Webgrind输出所示,我的应用程序将大部分处理时间花在YAML解析上。

Webgrind Output - 83.63 percent YAML parsing.

注意:Webgrind输出位于"%"。所以,加上"总自我成本"显示用于处理YAML的总时间的83.63%。

我已经看过这个相关主题:

Symfony2 Application Parses YML On Every Request

但是,我的实现是使用ApcClassLoader类,如下所示:

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

此外,我已经使用apc.php检查了APC系统,我的类和页面都在APC缓存中找到并被点击。即使在填充了缓存之后,这也会在PROD或DEV上发生。

我的理论是我们有一个循环实体引用,系统无法成功解析YAML以便缓存它。因此,它最终会尝试在每个请求中解析YAML。

但是,我没有看到任何关于无法解析YAML或日志中的任何内容的错误,并且不确定如何确定是否可能出现这种情况或下一步是什么情况。

2 个答案:

答案 0 :(得分:1)

我认为您的问题可能是递归的YAML资源(或类似的)。您将看到Yaml\Parser::parse的4000多次调用。在我自己的应用程序(这是相当复杂的)测试页面加载完全空缓存我只看到166调用。对于带有热缓存的页面加载,这会下降到2次调用。

我不认为您使用类加载器缓存会对YAML解析产生任何影响,正如您所发现的那样。我怀疑你链接的票可能是错误的)

答案 1 :(得分:1)

在逐步完成此过程中涉及的每一行代码后,我发现Doctrine正在使用默认的"数组"缓存,仅对单个页面加载有效。

我认为我和其他许多人都认为,当我们启用APC时,Doctrine也会使用它进行元数据缓存。实际上,除非另有说明,否则Doctrine默认为其数组缓存。

此页面列出了Doctrine配置选项:

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

向我的/app/config/config.yml添加缓存驱动程序选项后,如下所示:

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

修复后,同一页面显示没有 YAML解析器交互,并在302ms和5851ms之间加载,总加速为19X。此外,cachegrind文件从121MB到3.4MB,这些结果在许多试验中基本一致。

以下是显示差异的Webgrind:

Webgrind Fixed

所以,基本上,这是一个配置问题。从我在StackOverflow问题和其他论坛中看到的情况来看,这里似乎存在关于缓存如何工作的脱节。基本上,您需要如上所述明确地为Doctrine缓存启用它,或者它使用基本无用的默认值。

Symfony2有时也可以配置"这是一个我从未想过可以单独配置的实例。在这方面,它是一个强大的功能(能够使用单独的缓存),但是直到你弄明白这一点,就速度而言,系统完全受到了损害。