문제

Recently I integrated Doctrine 2 ORM into CodeIgniter 2. I configured Doctrine 2 as a library and autoloaded it in CodeIgniter. Within a page I instantiate doctrine entity manager in the following way:

private static $em = null;

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

And then I start to use the Entity Manager when needed. The issue I have is that in each page request Entity Manager takes some time to initialize (appr. 1 second). This causes the user to wait until the page is loaded. Below you can see some performance results I measured:

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

The GetArticle function basicly makes an EntityManager->find() call:

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

I have to wait that 1 second even if I use the EntityManager->createQuery() method.

In every page, I have a time loss of approximately 1 second because of EntityManager's first request.

Is this common?

Does this 1 second come from the fact that EntityManager needs to establish a connection to the DB? The functions/requests after the first request are quite fast though.

도움이 되었습니까?

해결책

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

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top