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:
parent
35c8cd7f23
commit
be94eb9d1f
@ -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.
|
||||||
*
|
*
|
||||||
@ -202,6 +209,7 @@ abstract class AbstractHydrator
|
|||||||
$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.
|
||||||
*
|
*
|
||||||
|
@ -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];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -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.
|
||||||
*
|
*
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user