1
0
mirror of synced 2025-01-18 22:41:43 +03:00

Made ClassMetadata to be reused during gatherRowData() and also during hydrateRow() to share same fetches instead of recalculating all info again. Performance improvement after 100x runs comparison is around 4%.

This commit is contained in:
Guilherme Blanco 2014-04-28 02:38:51 +00:00
parent 35c8cd7f23
commit be94eb9d1f
5 changed files with 32 additions and 58 deletions

View File

@ -64,6 +64,13 @@ abstract class AbstractHydrator
*/
protected $_uow;
/**
* Local ClassMetadata cache to avoid going to the EntityManager all the time.
*
* @var array
*/
protected $_metadataCache = array();
/**
* The cache used during row-by-row hydration.
*
@ -199,9 +206,10 @@ abstract class AbstractHydrator
{
$this->_stmt->closeCursor();
$this->_stmt = null;
$this->_rsm = null;
$this->_cache = array();
$this->_stmt = null;
$this->_rsm = null;
$this->_cache = array();
$this->_metadataCache = array();
}
/**
@ -403,12 +411,13 @@ abstract class AbstractHydrator
// NOTE: Most of the times it's a field mapping, so keep it first!!!
case (isset($this->_rsm->fieldMappings[$key])):
$fieldName = $this->_rsm->fieldMappings[$key];
$classMetadata = $this->_em->getClassMetadata($this->_rsm->declaringClasses[$key]);
$classMetadata = $this->getClassMetadata($this->_rsm->declaringClasses[$key]);
$fieldMapping = $classMetadata->fieldMappings[$fieldName];
return $this->_cache[$key] = array(
'isIdentifier' => $classMetadata->isIdentifier($fieldName),
'fieldName' => $fieldName,
'type' => Type::getType($classMetadata->fieldMappings[$fieldName]['type']),
'type' => Type::getType($fieldMapping['type']),
'dqlAlias' => $this->_rsm->columnOwnerMap[$key],
);
@ -437,7 +446,7 @@ abstract class AbstractHydrator
// Meta column (has meaning in relational schema only, i.e. foreign keys or discriminator columns).
$fieldName = $this->_rsm->metaMappings[$key];
$dqlAlias = $this->_rsm->columnOwnerMap[$key];
$classMetadata = $this->_em->getClassMetadata($this->_rsm->aliasMap[$dqlAlias]);
$classMetadata = $this->getClassMetadata($this->_rsm->aliasMap[$dqlAlias]);
$type = isset($this->_rsm->typeMappings[$key])
? Type::getType($this->_rsm->typeMappings[$key])
: null;
@ -456,6 +465,22 @@ abstract class AbstractHydrator
return null;
}
/**
* Retrieve ClassMetadata associated to entity class name.
*
* @param string $className
*
* @return \Doctrine\ORM\Mapping\ClassMetadata
*/
protected function getClassMetadata($className)
{
if ( ! isset($this->_metadataCache[$className])) {
$this->_metadataCache[$className] = $this->_em->getClassMetadata($className);
}
return $this->_metadataCache[$className];
}
/**
* Register entity as managed in UnitOfWork.
*

View File

@ -32,11 +32,6 @@ use Doctrine\ORM\Mapping\ClassMetadata;
*/
class ArrayHydrator extends AbstractHydrator
{
/**
* @var array
*/
private $_ce = array();
/**
* @var array
*/
@ -314,20 +309,4 @@ class ArrayHydrator extends AbstractHydrator
return;
}
/**
* Retrieve ClassMetadata associated to entity class name.
*
* @param string $className
*
* @return \Doctrine\ORM\Mapping\ClassMetadata
*/
private function getClassMetadata($className)
{
if ( ! isset($this->_ce[$className])) {
$this->_ce[$className] = $this->_em->getClassMetadata($className);
}
return $this->_ce[$className];
}
}

View File

@ -39,16 +39,6 @@ use Doctrine\ORM\Proxy\Proxy;
*/
class ObjectHydrator extends AbstractHydrator
{
/**
* Local ClassMetadata cache to avoid going to the EntityManager all the time.
* This local cache is maintained between hydration runs and not cleared.
*
* @var array
*/
private $ce = array();
/* The following parts are reinitialized on every hydration run. */
/**
* @var array
*/
@ -314,24 +304,6 @@ class ObjectHydrator extends AbstractHydrator
}
}
/**
* Gets a ClassMetadata instance from the local cache.
* If the instance is not yet in the local cache, it is loaded into the
* local cache.
*
* @param string $className The name of the class.
*
* @return ClassMetadata
*/
private function getClassMetadata($className)
{
if ( ! isset($this->ce[$className])) {
$this->ce[$className] = $this->_em->getClassMetadata($className);
}
return $this->ce[$className];
}
/**
* Hydrates a single row in an SQL result set.
*

View File

@ -36,7 +36,6 @@ class ScalarHydrator extends AbstractHydrator
protected function hydrateAllData()
{
$result = array();
$cache = array();
while ($data = $this->_stmt->fetch(\PDO::FETCH_ASSOC)) {
$this->hydrateRowData($data, $result);

View File

@ -51,8 +51,7 @@ class SingleScalarHydrator extends AbstractHydrator
throw new NonUniqueResultException('The query returned a row containing multiple columns. Change the query or use a different result function like getScalarResult().');
}
$cache = array();
$result = $this->gatherScalarRowData($data[key($data)], $cache);
$result = $this->gatherScalarRowData($data[key($data)]);
return array_shift($result);
}