From 4db7d733aa70f988878ff943ea428e7d5f864133 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Wed, 19 Jul 2017 14:20:35 +0200 Subject: [PATCH] Improve performance of the metadata system --- .../Factory/CachedPropertyMetadataFactory.php | 14 ++++++++++---- .../CachedPropertyNameCollectionFactory.php | 14 ++++++++++---- .../Factory/CachedResourceMetadataFactory.php | 13 +++++++++---- .../CachedResourceNameCollectionFactory.php | 11 ++++++++--- .../Factory/CachedPropertyMetadataFactoryTest.php | 13 ++++++++++--- .../CachedPropertyNameCollectionFactoryTest.php | 15 ++++++++++++--- .../Factory/CachedResourceMetadataFactoryTest.php | 12 +++++++++--- .../CachedResourceNameCollectionFactoryTest.php | 15 ++++++++++++--- 8 files changed, 80 insertions(+), 27 deletions(-) diff --git a/src/Metadata/Property/Factory/CachedPropertyMetadataFactory.php b/src/Metadata/Property/Factory/CachedPropertyMetadataFactory.php index 9b2f36713a8..7acaef6953e 100644 --- a/src/Metadata/Property/Factory/CachedPropertyMetadataFactory.php +++ b/src/Metadata/Property/Factory/CachedPropertyMetadataFactory.php @@ -28,6 +28,7 @@ final class CachedPropertyMetadataFactory implements PropertyMetadataFactoryInte private $cacheItemPool; private $decorated; + private $memoryCache = []; public function __construct(CacheItemPoolInterface $cacheItemPool, PropertyMetadataFactoryInterface $decorated) { @@ -40,13 +41,18 @@ public function __construct(CacheItemPoolInterface $cacheItemPool, PropertyMetad */ public function create(string $resourceClass, string $property, array $options = []): PropertyMetadata { - $cacheKey = self::CACHE_KEY_PREFIX.md5(serialize([$resourceClass, $property, $options])); + $localKey = serialize([$resourceClass, $property, $options]); + if (isset($this->memoryCache[$localKey])) { + return $this->memoryCache[$localKey]; + } + + $cacheKey = self::CACHE_KEY_PREFIX.md5($localKey); try { $cacheItem = $this->cacheItemPool->getItem($cacheKey); if ($cacheItem->isHit()) { - return $cacheItem->get(); + return $this->memoryCache[$localKey] = $cacheItem->get(); } } catch (CacheException $e) { // do nothing @@ -55,12 +61,12 @@ public function create(string $resourceClass, string $property, array $options = $propertyMetadata = $this->decorated->create($resourceClass, $property, $options); if (!isset($cacheItem)) { - return $propertyMetadata; + return $this->memoryCache[$localKey] = $propertyMetadata; } $cacheItem->set($propertyMetadata); $this->cacheItemPool->save($cacheItem); - return $propertyMetadata; + return $this->memoryCache[$localKey] = $propertyMetadata; } } diff --git a/src/Metadata/Property/Factory/CachedPropertyNameCollectionFactory.php b/src/Metadata/Property/Factory/CachedPropertyNameCollectionFactory.php index 1856129a05d..e48d719d62d 100644 --- a/src/Metadata/Property/Factory/CachedPropertyNameCollectionFactory.php +++ b/src/Metadata/Property/Factory/CachedPropertyNameCollectionFactory.php @@ -28,6 +28,7 @@ final class CachedPropertyNameCollectionFactory implements PropertyNameCollectio private $cacheItemPool; private $decorated; + private $memoryCache = []; public function __construct(CacheItemPoolInterface $cacheItemPool, PropertyNameCollectionFactoryInterface $decorated) { @@ -40,13 +41,18 @@ public function __construct(CacheItemPoolInterface $cacheItemPool, PropertyNameC */ public function create(string $resourceClass, array $options = []): PropertyNameCollection { - $cacheKey = self::CACHE_KEY_PREFIX.md5(serialize([$resourceClass, $options])); + $localKey = serialize([$resourceClass, $options]); + if (isset($this->memoryCache[$localKey])) { + return $this->memoryCache[$localKey]; + } + + $cacheKey = self::CACHE_KEY_PREFIX.md5($localKey); try { $cacheItem = $this->cacheItemPool->getItem($cacheKey); if ($cacheItem->isHit()) { - return $cacheItem->get(); + return $this->memoryCache[$localKey] = $cacheItem->get(); } } catch (CacheException $e) { // do nothing @@ -55,12 +61,12 @@ public function create(string $resourceClass, array $options = []): PropertyName $propertyNameCollection = $this->decorated->create($resourceClass, $options); if (!isset($cacheItem)) { - return $propertyNameCollection; + return $this->memoryCache[$localKey] = $propertyNameCollection; } $cacheItem->set($propertyNameCollection); $this->cacheItemPool->save($cacheItem); - return $propertyNameCollection; + return $this->memoryCache[$localKey] = $propertyNameCollection; } } diff --git a/src/Metadata/Resource/Factory/CachedResourceMetadataFactory.php b/src/Metadata/Resource/Factory/CachedResourceMetadataFactory.php index 4c0445d35b1..da533c558fe 100644 --- a/src/Metadata/Resource/Factory/CachedResourceMetadataFactory.php +++ b/src/Metadata/Resource/Factory/CachedResourceMetadataFactory.php @@ -28,6 +28,7 @@ final class CachedResourceMetadataFactory implements ResourceMetadataFactoryInte private $cacheItemPool; private $decorated; + private $memoryCache = []; public function __construct(CacheItemPoolInterface $cacheItemPool, ResourceMetadataFactoryInterface $decorated) { @@ -40,13 +41,17 @@ public function __construct(CacheItemPoolInterface $cacheItemPool, ResourceMetad */ public function create(string $resourceClass): ResourceMetadata { - $cacheKey = self::CACHE_KEY_PREFIX.md5(serialize([$resourceClass])); + if (isset($this->memoryCache[$resourceClass])) { + return $this->memoryCache[$resourceClass]; + } + + $cacheKey = self::CACHE_KEY_PREFIX.md5($resourceClass); try { $cacheItem = $this->cacheItemPool->getItem($cacheKey); if ($cacheItem->isHit()) { - return $cacheItem->get(); + return $this->memoryCache[$resourceClass] = $cacheItem->get(); } } catch (CacheException $e) { // do nothing @@ -55,12 +60,12 @@ public function create(string $resourceClass): ResourceMetadata $resourceMetadata = $this->decorated->create($resourceClass); if (!isset($cacheItem)) { - return $resourceMetadata; + return $this->memoryCache[$resourceClass] = $resourceMetadata; } $cacheItem->set($resourceMetadata); $this->cacheItemPool->save($cacheItem); - return $resourceMetadata; + return $this->memoryCache[$resourceClass] = $resourceMetadata; } } diff --git a/src/Metadata/Resource/Factory/CachedResourceNameCollectionFactory.php b/src/Metadata/Resource/Factory/CachedResourceNameCollectionFactory.php index 54df86b2b5e..0052b8f5896 100644 --- a/src/Metadata/Resource/Factory/CachedResourceNameCollectionFactory.php +++ b/src/Metadata/Resource/Factory/CachedResourceNameCollectionFactory.php @@ -28,6 +28,7 @@ final class CachedResourceNameCollectionFactory implements ResourceNameCollectio private $cacheItemPool; private $decorated; + private $memoryCache = []; public function __construct(CacheItemPoolInterface $cacheItemPool, ResourceNameCollectionFactoryInterface $decorated) { @@ -40,11 +41,15 @@ public function __construct(CacheItemPoolInterface $cacheItemPool, ResourceNameC */ public function create(): ResourceNameCollection { + if (isset($this->memoryCache[self::CACHE_KEY])) { + return $this->memoryCache[self::CACHE_KEY]; + } + try { $cacheItem = $this->cacheItemPool->getItem(self::CACHE_KEY); if ($cacheItem->isHit()) { - return $cacheItem->get(); + return $this->memoryCache[self::CACHE_KEY] = $cacheItem->get(); } } catch (CacheException $e) { // do nothing @@ -53,12 +58,12 @@ public function create(): ResourceNameCollection $resourceNameCollection = $this->decorated->create(); if (!isset($cacheItem)) { - return $resourceNameCollection; + return $this->memoryCache[self::CACHE_KEY] = $resourceNameCollection; } $cacheItem->set($resourceNameCollection); $this->cacheItemPool->save($cacheItem); - return $resourceNameCollection; + return $this->memoryCache[self::CACHE_KEY] = $resourceNameCollection; } } diff --git a/tests/Metadata/Property/Factory/CachedPropertyMetadataFactoryTest.php b/tests/Metadata/Property/Factory/CachedPropertyMetadataFactoryTest.php index 6bab006d040..0d2b3dd3f31 100644 --- a/tests/Metadata/Property/Factory/CachedPropertyMetadataFactoryTest.php +++ b/tests/Metadata/Property/Factory/CachedPropertyMetadataFactoryTest.php @@ -41,7 +41,9 @@ public function testCreateWithItemHit() $resultedPropertyMetadata = $cachedPropertyMetadataFactory->create(Dummy::class, 'dummy'); $this->assertInstanceOf(PropertyMetadata::class, $resultedPropertyMetadata); - $this->assertEquals(new PropertyMetadata(null, 'A dummy', true, true, null, null, false, false), $resultedPropertyMetadata); + $expectedResult = new PropertyMetadata(null, 'A dummy', true, true, null, null, false, false); + $this->assertEquals($expectedResult, $resultedPropertyMetadata); + $this->assertEquals($expectedResult, $cachedPropertyMetadataFactory->create(Dummy::class, 'dummy'), 'Trigger the local cache'); } public function testCreateWithItemNotHit() @@ -63,7 +65,9 @@ public function testCreateWithItemNotHit() $resultedPropertyMetadata = $cachedPropertyMetadataFactory->create(Dummy::class, 'dummy'); $this->assertInstanceOf(PropertyMetadata::class, $resultedPropertyMetadata); - $this->assertEquals(new PropertyMetadata(null, 'A dummy', true, true, null, null, false, false), $resultedPropertyMetadata); + $expectedResult = new PropertyMetadata(null, 'A dummy', true, true, null, null, false, false); + $this->assertEquals($expectedResult, $resultedPropertyMetadata); + $this->assertEquals($expectedResult, $cachedPropertyMetadataFactory->create(Dummy::class, 'dummy'), 'Trigger the local cache'); } public function testCreateWithGetCacheItemThrowsCacheException() @@ -81,7 +85,10 @@ public function testCreateWithGetCacheItemThrowsCacheException() $resultedPropertyMetadata = $cachedPropertyMetadataFactory->create(Dummy::class, 'dummy'); $this->assertInstanceOf(PropertyMetadata::class, $resultedPropertyMetadata); - $this->assertEquals(new PropertyMetadata(null, 'A dummy', true, true, null, null, false, false), $resultedPropertyMetadata); + + $expectedResult = new PropertyMetadata(null, 'A dummy', true, true, null, null, false, false); + $this->assertEquals($expectedResult, $resultedPropertyMetadata); + $this->assertEquals($expectedResult, $cachedPropertyMetadataFactory->create(Dummy::class, 'dummy'), 'Trigger the local cache'); } private function generateCacheKey(string $resourceClass = Dummy::class, string $property = 'dummy', array $options = []) diff --git a/tests/Metadata/Property/Factory/CachedPropertyNameCollectionFactoryTest.php b/tests/Metadata/Property/Factory/CachedPropertyNameCollectionFactoryTest.php index 6f58b377e7d..08b89b846f6 100644 --- a/tests/Metadata/Property/Factory/CachedPropertyNameCollectionFactoryTest.php +++ b/tests/Metadata/Property/Factory/CachedPropertyNameCollectionFactoryTest.php @@ -41,7 +41,10 @@ public function testCreateWithItemHit() $resultedPropertyNameCollection = $cachedPropertyNameCollectionFactory->create(Dummy::class); $this->assertInstanceOf(PropertyNameCollection::class, $resultedPropertyNameCollection); - $this->assertEquals(new PropertyNameCollection(['id', 'name', 'description', 'dummy']), $resultedPropertyNameCollection); + + $expectedResult = new PropertyNameCollection(['id', 'name', 'description', 'dummy']); + $this->assertEquals($expectedResult, $resultedPropertyNameCollection); + $this->assertEquals($expectedResult, $cachedPropertyNameCollectionFactory->create(Dummy::class), 'Trigger the local cache'); } public function testCreateWithItemNotHit() @@ -63,7 +66,10 @@ public function testCreateWithItemNotHit() $resultedPropertyNameCollection = $cachedPropertyNameCollectionFactory->create(Dummy::class); $this->assertInstanceOf(PropertyNameCollection::class, $resultedPropertyNameCollection); - $this->assertEquals(new PropertyNameCollection(['id', 'name', 'description', 'dummy']), $resultedPropertyNameCollection); + + $expectedResult = new PropertyNameCollection(['id', 'name', 'description', 'dummy']); + $this->assertEquals($expectedResult, $resultedPropertyNameCollection); + $this->assertEquals($expectedResult, $cachedPropertyNameCollectionFactory->create(Dummy::class), 'Trigger the local cache'); } public function testCreateWithGetCacheItemThrowsCacheException() @@ -81,7 +87,10 @@ public function testCreateWithGetCacheItemThrowsCacheException() $resultedPropertyNameCollection = $cachedPropertyNameCollectionFactory->create(Dummy::class); $this->assertInstanceOf(PropertyNameCollection::class, $resultedPropertyNameCollection); - $this->assertEquals(new PropertyNameCollection(['id', 'name', 'description', 'dummy']), $resultedPropertyNameCollection); + + $expectedResult = new PropertyNameCollection(['id', 'name', 'description', 'dummy']); + $this->assertEquals($expectedResult, $resultedPropertyNameCollection); + $this->assertEquals($expectedResult, $cachedPropertyNameCollectionFactory->create(Dummy::class), 'Trigger the local cache'); } private function generateCacheKey(string $resourceClass = Dummy::class, array $options = []) diff --git a/tests/Metadata/Resource/Factory/CachedResourceMetadataFactoryTest.php b/tests/Metadata/Resource/Factory/CachedResourceMetadataFactoryTest.php index 00d4903c2d2..3d4c1162a99 100644 --- a/tests/Metadata/Resource/Factory/CachedResourceMetadataFactoryTest.php +++ b/tests/Metadata/Resource/Factory/CachedResourceMetadataFactoryTest.php @@ -63,7 +63,10 @@ public function testCreateWithItemNotHit() $resultedResourceMetadata = $cachedResourceMetadataFactory->create(Dummy::class); $this->assertInstanceOf(ResourceMetadata::class, $resultedResourceMetadata); - $this->assertEquals(new ResourceMetadata(null, 'Dummy.'), $resultedResourceMetadata); + + $expectedResult = new ResourceMetadata(null, 'Dummy.'); + $this->assertEquals($expectedResult, $resultedResourceMetadata); + $this->assertEquals($expectedResult, $cachedResourceMetadataFactory->create(Dummy::class), 'Trigger the local cache'); } public function testCreateWithGetCacheItemThrowsCacheException() @@ -81,11 +84,14 @@ public function testCreateWithGetCacheItemThrowsCacheException() $resultedResourceMetadata = $cachedResourceMetadataFactory->create(Dummy::class); $this->assertInstanceOf(ResourceMetadata::class, $resultedResourceMetadata); - $this->assertEquals(new ResourceMetadata(null, 'Dummy.'), $resultedResourceMetadata); + + $expectedResult = new ResourceMetadata(null, 'Dummy.'); + $this->assertEquals($expectedResult, $resultedResourceMetadata); + $this->assertEquals($expectedResult, $cachedResourceMetadataFactory->create(Dummy::class), 'Trigger the local cache'); } private function generateCacheKey(string $resourceClass = Dummy::class) { - return CachedResourceMetadataFactory::CACHE_KEY_PREFIX.md5(serialize([$resourceClass])); + return CachedResourceMetadataFactory::CACHE_KEY_PREFIX.md5($resourceClass); } } diff --git a/tests/Metadata/Resource/Factory/CachedResourceNameCollectionFactoryTest.php b/tests/Metadata/Resource/Factory/CachedResourceNameCollectionFactoryTest.php index 76207f50350..171f973571c 100644 --- a/tests/Metadata/Resource/Factory/CachedResourceNameCollectionFactoryTest.php +++ b/tests/Metadata/Resource/Factory/CachedResourceNameCollectionFactoryTest.php @@ -41,7 +41,10 @@ public function testCreateWithItemHit() $resultedResourceNameCollection = $cachedResourceNameCollectionFactory->create(); $this->assertInstanceOf(ResourceNameCollection::class, $resultedResourceNameCollection); - $this->assertEquals(new ResourceNameCollection([Dummy::class]), $resultedResourceNameCollection); + + $expectedResult = new ResourceNameCollection([Dummy::class]); + $this->assertEquals($expectedResult, $resultedResourceNameCollection); + $this->assertEquals($expectedResult, $cachedResourceNameCollectionFactory->create(), 'Trigger the local cache'); } public function testCreateWithItemNotHit() @@ -63,7 +66,10 @@ public function testCreateWithItemNotHit() $resultedResourceNameCollection = $cachedResourceNameCollectionFactory->create(); $this->assertInstanceOf(ResourceNameCollection::class, $resultedResourceNameCollection); - $this->assertEquals(new ResourceNameCollection([Dummy::class]), $resultedResourceNameCollection); + + $expectedResult = new ResourceNameCollection([Dummy::class]); + $this->assertEquals($expectedResult, $resultedResourceNameCollection); + $this->assertEquals($expectedResult, $cachedResourceNameCollectionFactory->create(), 'Trigger the local cache'); } public function testCreateWithGetCacheItemThrowsCacheException() @@ -81,6 +87,9 @@ public function testCreateWithGetCacheItemThrowsCacheException() $resultedResourceNameCollection = $cachedResourceNameCollectionFactory->create(); $this->assertInstanceOf(ResourceNameCollection::class, $resultedResourceNameCollection); - $this->assertEquals(new ResourceNameCollection([Dummy::class]), $resultedResourceNameCollection); + + $expectedResult = new ResourceNameCollection([Dummy::class]); + $this->assertEquals($expectedResult, $resultedResourceNameCollection); + $this->assertEquals($expectedResult, $cachedResourceNameCollectionFactory->create(), 'Trigger the local cache'); } }