Skip to content
Permalink
Browse files

Major performance improvements into the Mapper:

* introduced doctrine cache for retrieving annotations
* introduced a simpler cache for casting
* introduced a simpler cache for class mapping
* inflection is cached with a simple cache
  • Loading branch information...
odino committed Jan 25, 2013
1 parent e66d22a commit df875c946e02a9c84eee22f0c86e0a3b06bd70ec
Showing with 124 additions and 20 deletions.
  1. +71 −20 src/Doctrine/ODM/OrientDB/Mapper.php
  2. +53 −0 src/Doctrine/OrientDB/Util/Inflector/Cached.php
@@ -33,9 +33,11 @@
use Doctrine\OrientDB\Exception;
use Doctrine\OrientDB\Query\Query;
use Doctrine\OrientDB\Filesystem\Iterator\Regex as RegexIterator;
use Doctrine\Common\Util\Inflector as DoctrineInflector;
use Doctrine\OrientDB\Util\Inflector\Cached as Inflector;
use Doctrine\Common\Annotations\AnnotationReader;
use Symfony\Component\Finder\Finder;
use Doctrine\Common\Cache\Cache;
use Doctrine\Common\Cache\ArrayCache;
class Mapper
{
@@ -44,6 +46,10 @@ class Mapper
protected $annotationReader;
protected $inflector;
protected $documentProxiesDirectory;
protected $classMap = array();
protected $cache;
protected $caster;
protected $castedProperties = array();
const ANNOTATION_PROPERTY_CLASS = 'Doctrine\ODM\OrientDB\Mapper\Annotations\Property';
const ANNOTATION_CLASS_CLASS = 'Doctrine\ODM\OrientDB\Mapper\Annotations\Document';
@@ -54,16 +60,20 @@ class Mapper
*
* @param string $documentProxyDirectory
* @param AnnotationReaderInterface $annotationReader
* @param DoctrineInflector $inflector
* @param Inflector $inflector
*/
public function __construct(
$documentProxyDirectory,
AnnotationReaderInterface $annotationReader = null,
DoctrineInflector $inflector = null
Inflector $inflector = null,
Cache $cache = null,
Caster $caster = null
) {
$this->documentProxyDirectory = $documentProxyDirectory;
$this->annotationReader = $annotationReader ?: new Reader;
$this->inflector = $inflector ?: new DoctrineInflector;
$this->documentProxyDirectory = $documentProxyDirectory;
$this->annotationReader = $annotationReader ?: new Reader;
$this->cache = $cache ?: new ArrayCache;
$this->inflector = $inflector ?: new Inflector();
$this->caster = $caster ?: new Caster($this);
}
/**
@@ -222,14 +232,34 @@ protected function createDocument($class, \stdClass $orientObject, LinkTracker $
*/
protected function castProperty($annotation, $propertyValue)
{
$caster = new Caster($this);
$method = 'cast' . $this->inflector->camelize($annotation->type);
$propertyId = $this->getCastedPropertyCacheKey($annotation->type, $propertyValue);
if (!isset($this->castedProperties[$propertyId])) {
$method = 'cast' . $this->inflector->camelize($annotation->type);
$caster->setValue($propertyValue);
$caster->setProperty('annotation', $annotation);
$this->verifyCastingSupport($caster, $method, $annotation->type);
$this->getCaster()->setValue($propertyValue);
$this->getCaster()->setProperty('annotation', $annotation);
$this->verifyCastingSupport($this->getCaster(), $method, $annotation->type);
return $caster->$method();
$this->castedProperties[$propertyId] = $this->getCaster()->$method();
}
return $this->castedProperties[$propertyId];
}
protected function getCastedPropertyCacheKey($type, $value)
{
return get_class() . "_casted_property_" . $type . "_" . serialize($value);
}
/**
* Returns the caching layer of the mapper.
*
* @return Doctrine\Common\Cache\Cache
*/
protected function getCache()
{
return $this->cache;
}
/**
@@ -297,6 +327,10 @@ protected function findClassMappingInDirectories($OClass)
protected function findClassMappingInDirectory($OClass, $directory, $namespace)
{
$finder = new Finder();
if (isset($this->classMap[$OClass])) {
return $this->classMap[$OClass];
}
foreach ($finder->files()->name('*.php')->in($directory) as $file) {
$class = $this->getClassByPath($file, $namespace);
@@ -305,6 +339,7 @@ protected function findClassMappingInDirectory($OClass, $directory, $namespace)
$annotation = $this->getClassAnnotation($class);
if ($annotation && $annotation->hasMatchingClass($OClass)) {
$this->classMap[$OClass] = $class;
return $class;
}
}
@@ -415,6 +450,16 @@ class $proxyClassName extends $class
file_put_contents("$dir/$proxyClassName.php", $proxy);
}
/**
* Returns the caster instance.
*
* @return Doctrine\ODM\OrientDB\Caster\Caster
*/
protected function getCaster()
{
return $this->caster;
}
/**
* Returns the directory in which all the documents' proxy classes are
@@ -465,18 +510,24 @@ protected function getProxyClass($class)
*/
protected function getObjectPropertyAnnotations($document)
{
$refObject = new \ReflectionObject($document);
$annotations = array();
$cacheKey = "object_property_annotations_" . get_class($document);
if (!$this->getCache()->contains($cacheKey)) {
$refObject = new \ReflectionObject($document);
$annotations = array();
foreach ($refObject->getProperties() as $property) {
$annotation = $this->getPropertyAnnotation($property);
foreach ($refObject->getProperties() as $property) {
$annotation = $this->getPropertyAnnotation($property);
if ($annotation) {
$annotations[$property->getName()] = $annotation;
if ($annotation) {
$annotations[$property->getName()] = $annotation;
}
}
}
return $annotations;
$this->getCache()->save($cacheKey, $annotations);
}
return $this->getCache()->fetch($cacheKey);
}
/**
@@ -0,0 +1,53 @@
<?php
namespace Doctrine\OrientDB\Util\Inflector;
use Doctrine\Common\Util\Inflector;
use Doctrine\Common\Cache\Cache;
class Cached extends Inflector
{
protected static $cache = array();

This comment has been minimized.

Copy link
@vicb

vicb Jan 25, 2013

Contributor

why not 3 arrays ? this would remove the need for concatenation & saves both mem & cpu.

This comment has been minimized.

Copy link
@odino

odino Jan 25, 2013

Author Member

hi @vicb,

we are planning to refactor this cached inflector, having all the methods calling static::fromCache($method, $word), otherwise for each method we would add, we need to add an array, which isnt elegant.

This comment has been minimized.

Copy link
@vicb

vicb Jan 25, 2013

Contributor

The could be nested arrays also array('tableize'=>array(), ...)

This comment has been minimized.

Copy link
@odino

odino Jan 27, 2013

Author Member

right, will have a look at it or, if you want, you can open a PR ;)

This comment has been minimized.

Copy link
@vicb

vicb Jan 28, 2013

Contributor

That's a ~20% gain to expect (see https://gist.github.com/4654233) plus gain in mem consumption, I'll submit a PR.

This comment has been minimized.

Copy link
@odino

odino Jan 28, 2013

Author Member

great! :)

/**
* @inheritdoc
*/
public static function tableize($word)
{
$cacheKey = "tableize_" . $word;
if (!isset(static::$cache[$cacheKey])) {
static::$cache[$cacheKey] = parent::tableize($word);
}
return static::$cache[$cacheKey];
}
/**
* @inheritdoc
*/
public static function classify($word)
{
$cacheKey = "classify_" . $word;
if (!isset(static::$cache[$cacheKey])) {
static::$cache[$cacheKey] = parent::classify($word);
}
return static::$cache[$cacheKey];
}
/**
* @inheritdoc
*/
public static function camelize($word)
{
$cacheKey = "camelize_" . $word;
if (!isset(static::$cache[$cacheKey])) {
static::$cache[$cacheKey] = parent::camelize($word);
}
return static::$cache[$cacheKey];
}
}

0 comments on commit df875c9

Please sign in to comment.
You can’t perform that action at this time.