0

最近我将 Doctrine 2 ORM 集成到 CodeIgniter 2 中。我将 Doctrine 2 配置为一个库并在 CodeIgniter 中自动加载它。在一个页面中,我通过以下方式实例化理论实体管理器:

private static $em = null;

public function __construct() {
    parent::__construct();
    $this->em = $this->doctrine->em;
}

然后我在需要时开始使用实体管理器。我遇到的问题是,在每个页面请求中,实体管理器都需要一些时间来初始化(大约 1 秒)。这会导致用户等到页面加载完毕。下面你可以看到我测量的一些性能结果:

BENCHMARKS  
Loading Time: Base Classes          0.0166
Doctrine                            0.0486
GetArticle                          1.0441
Functions                           0.0068
Controller Execution Time           1.1770
Total Execution Time                1.1938

GetArticle 函数基本上进行 EntityManager->find() 调用:

$currentart = $this->em->find('Entities\Article', $artid);

即使我使用 EntityManager->createQuery() 方法,我也必须等待 1 秒。

在每一页中,由于 EntityManager 的第一个请求,我有大约 1 秒的时间损失。

这很常见吗?

这 1 秒是否来自 EntityManager 需要建立与数据库的连接这一事实?不过,第一次请求之后的功能/请求非常快。

4

1 回答 1

1

The most time consuming thing that Doctrine does is load metadata for your entities, whether it's annotations, XML, or YAML. Doctrine lazy loads the metadata when possible, so you will not see the performance hit until you start using entities. Since the metadata doesn't change unless you make changes in your code, Doctrine allows you to cache the metadata across requests. DQL queries also need to be parsed into SQL, so Doctrine provides another caching configuration for this.

In a production environment you should set these caches up (it sounds like you have already, but for others reading this):

$cache = new \Doctrine\Common\Cache\ApcCache(); // or MemcacheCache $configuration->setMetadataCachImpl($cache); // caches metadata for entities $configuration->setQueryCachImpl($cache); // caches SQL from DQL queries

In order to prevent the first page load from taking the full metadata load, you can set up a cache warmer that loads all of the class metadata and save it to the cache.

$em->getMetadataFactory()->getAllMetadata();

Another potential bottleneck is the generation of proxy classes. If this is not configured correctly in a production environment, Doctrine will generate the classes and save them to the file system on every page load. These proxy classes do not change unless the entity's code changes, so it is again unnecessary for this to happen. To speed things up, you should generate the proxies using the command line tool (orm:generate-proxies) and disable auto-generation:

$configuration->setAutoGenerateProxyClasses(false);

Hopefully this helps you out. Some more information can be found at http://www.doctrine-project.org/docs/orm/2.0/en/reference/improving-performance.html#bytecode-cache

于 2011-07-25T18:17:39.400 回答