最近我将Doctrine 2 ORM集成到CodeIgniter 2.我将Doctrine 2配置为库并在CodeIgniter中自动加载它。在页面中,我通过以下方式实例化doctrine实体管理器:
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需要与DB建立连接的事实?第一次请求后的函数/请求非常快。
答案 0 :(得分:1)
Doctrine所做的最耗时的事情是为您的实体加载元数据,无论是注释,XML还是YAML。如果可能,Doctrine lazy会加载元数据,因此在开始使用实体之前,您不会看到性能影响。由于除非您对代码进行更改,否则元数据不会更改,因此Doctrine允许您跨请求缓存元数据。 DQL查询也需要解析为SQL,因此Doctrine为此提供了另一种缓存配置。
在生产环境中,你应该设置这些缓存(听起来你已经有了,但是对于其他人来说这个):
$cache = new \Doctrine\Common\Cache\ApcCache(); // or MemcacheCache
$configuration->setMetadataCachImpl($cache); // caches metadata for entities
$configuration->setQueryCachImpl($cache); // caches SQL from DQL queries
为了防止第一页加载完成元数据加载,您可以设置一个缓存加热器,加载所有类元数据并将其保存到缓存中。
$em->getMetadataFactory()->getAllMetadata();
另一个潜在的瓶颈是生成代理类。如果在生产环境中未正确配置,则Doctrine将生成类并在每次加载页面时将它们保存到文件系统。除非实体的代码发生更改,否则这些代理类不会更改,因此再次发生这种情况也是不必要的。为了加快速度,您应该使用命令行工具(orm:generate-proxies)生成代理并禁用自动生成:
$configuration->setAutoGenerateProxyClasses(false);
希望这会帮助你。可以在http://www.doctrine-project.org/docs/orm/2.0/en/reference/improving-performance.html#bytecode-cache
找到更多信息