1
0
mirror of synced 2025-01-19 06:51:40 +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; 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. * The cache used during row-by-row hydration.
* *
@ -199,9 +206,10 @@ abstract class AbstractHydrator
{ {
$this->_stmt->closeCursor(); $this->_stmt->closeCursor();
$this->_stmt = null; $this->_stmt = null;
$this->_rsm = null; $this->_rsm = null;
$this->_cache = array(); $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!!! // NOTE: Most of the times it's a field mapping, so keep it first!!!
case (isset($this->_rsm->fieldMappings[$key])): case (isset($this->_rsm->fieldMappings[$key])):
$fieldName = $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( return $this->_cache[$key] = array(
'isIdentifier' => $classMetadata->isIdentifier($fieldName), 'isIdentifier' => $classMetadata->isIdentifier($fieldName),
'fieldName' => $fieldName, 'fieldName' => $fieldName,
'type' => Type::getType($classMetadata->fieldMappings[$fieldName]['type']), 'type' => Type::getType($fieldMapping['type']),
'dqlAlias' => $this->_rsm->columnOwnerMap[$key], '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). // Meta column (has meaning in relational schema only, i.e. foreign keys or discriminator columns).
$fieldName = $this->_rsm->metaMappings[$key]; $fieldName = $this->_rsm->metaMappings[$key];
$dqlAlias = $this->_rsm->columnOwnerMap[$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 = isset($this->_rsm->typeMappings[$key])
? Type::getType($this->_rsm->typeMappings[$key]) ? Type::getType($this->_rsm->typeMappings[$key])
: null; : null;
@ -456,6 +465,22 @@ abstract class AbstractHydrator
return null; 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. * Register entity as managed in UnitOfWork.
* *

View File

@ -32,11 +32,6 @@ use Doctrine\ORM\Mapping\ClassMetadata;
*/ */
class ArrayHydrator extends AbstractHydrator class ArrayHydrator extends AbstractHydrator
{ {
/**
* @var array
*/
private $_ce = array();
/** /**
* @var array * @var array
*/ */
@ -314,20 +309,4 @@ class ArrayHydrator extends AbstractHydrator
return; 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 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 * @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. * Hydrates a single row in an SQL result set.
* *

View File

@ -36,7 +36,6 @@ class ScalarHydrator extends AbstractHydrator
protected function hydrateAllData() protected function hydrateAllData()
{ {
$result = array(); $result = array();
$cache = array();
while ($data = $this->_stmt->fetch(\PDO::FETCH_ASSOC)) { while ($data = $this->_stmt->fetch(\PDO::FETCH_ASSOC)) {
$this->hydrateRowData($data, $result); $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().'); 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)]);
$result = $this->gatherScalarRowData($data[key($data)], $cache);
return array_shift($result); return array_shift($result);
} }