From 9db95c65ac1c478b06aa2e964bd7b24688af9577 Mon Sep 17 00:00:00 2001 From: Thibaud Fabre Date: Wed, 20 Jan 2016 14:41:18 +0100 Subject: [PATCH] Add timing for cache profile and use call stats for toolbar --- .../Subscriber/CacheStatisticsSubscriber.php | 9 ++++ .../Core/Profiler/CacheDataCollector.php | 23 ++++++++-- .../Core/Profiler/CacheProfileSummary.php | 40 ++++++++++++++---- .../Phrasea/Core/Profiler/TraceableCache.php | 42 ++++++++++++++++--- templates-profiler/cache.html.twig | 6 ++- 5 files changed, 102 insertions(+), 18 deletions(-) diff --git a/lib/Alchemy/Phrasea/Core/Event/Subscriber/CacheStatisticsSubscriber.php b/lib/Alchemy/Phrasea/Core/Event/Subscriber/CacheStatisticsSubscriber.php index ab39cc8dd5..c0f05b6def 100644 --- a/lib/Alchemy/Phrasea/Core/Event/Subscriber/CacheStatisticsSubscriber.php +++ b/lib/Alchemy/Phrasea/Core/Event/Subscriber/CacheStatisticsSubscriber.php @@ -66,6 +66,15 @@ class CacheStatisticsSubscriber implements EventSubscriberInterface return []; } + public function getTimeSpent() + { + if ($this->cache instanceof TraceableCache) { + return $this->cache->getTotalTime(); + } + + return 0; + } + public function getCacheType() { return $this->cacheType; diff --git a/lib/Alchemy/Phrasea/Core/Profiler/CacheDataCollector.php b/lib/Alchemy/Phrasea/Core/Profiler/CacheDataCollector.php index d0d6bdc6a8..893c6bceb6 100644 --- a/lib/Alchemy/Phrasea/Core/Profiler/CacheDataCollector.php +++ b/lib/Alchemy/Phrasea/Core/Profiler/CacheDataCollector.php @@ -30,6 +30,11 @@ class CacheDataCollector implements DataCollectorInterface */ private $summary; + /** + * @var int + */ + private $timeSpent = 0; + /** * @var array */ @@ -70,15 +75,17 @@ class CacheDataCollector implements DataCollectorInterface $this->startProfile = new CacheProfile($this->statsListener->getInitialStats() ?: []); $this->endProfile = new CacheProfile($this->statsListener->getCurrentStats() ?: []); + $this->timeSpent = $this->statsListener->getTimeSpent(); + $this->calls = $this->statsListener->getCalls(); + $this->callSummary = $this->statsListener->getCallSummary(); + $this->summary = new CacheProfileSummary( $this->statsListener->getCacheType(), $this->statsListener->getCacheNamespace(), $this->startProfile, - $this->endProfile + $this->endProfile, + $this->callSummary ); - - $this->calls = $this->statsListener->getCalls(); - $this->callSummary = $this->statsListener->getCallSummary(); } /** @@ -97,6 +104,14 @@ class CacheDataCollector implements DataCollectorInterface return $this->endProfile; } + /** + * @return int + */ + public function getTotalTime() + { + return $this->timeSpent; + } + public function getCalls() { return $this->calls; diff --git a/lib/Alchemy/Phrasea/Core/Profiler/CacheProfileSummary.php b/lib/Alchemy/Phrasea/Core/Profiler/CacheProfileSummary.php index 67bcc481e6..80ab9d864e 100644 --- a/lib/Alchemy/Phrasea/Core/Profiler/CacheProfileSummary.php +++ b/lib/Alchemy/Phrasea/Core/Profiler/CacheProfileSummary.php @@ -24,18 +24,30 @@ class CacheProfileSummary */ private $finalProfile; + /** + * @var array + */ + private $callSummaryData; + /** * @param string $cacheType * @param string $namespace * @param CacheProfile $initialProfile * @param CacheProfile $finalProfile + * @param array $callSummaryData */ - public function __construct($cacheType, $namespace, CacheProfile $initialProfile, CacheProfile $finalProfile) - { - $this->cacheType = (string) $cacheType; - $this->cacheNamespace = (string) $namespace; + public function __construct( + $cacheType, + $namespace, + CacheProfile $initialProfile, + CacheProfile $finalProfile, + array $callSummaryData + ) { + $this->cacheType = (string)$cacheType; + $this->cacheNamespace = (string)$namespace; $this->initialProfile = $initialProfile; $this->finalProfile = $finalProfile; + $this->callSummaryData = $callSummaryData; } /** @@ -59,7 +71,11 @@ class CacheProfileSummary */ public function getHits() { - return (int) max(0, $this->finalProfile->getHits() - $this->initialProfile->getHits()); + if (isset($this->callSummaryData['hits'])) { + return (int) $this->callSummaryData['hits']; + } + + return (int)max(0, $this->finalProfile->getHits() - $this->initialProfile->getHits()); } /** @@ -67,7 +83,11 @@ class CacheProfileSummary */ public function getMisses() { - return (int) max(0, $this->finalProfile->getMisses() - $this->initialProfile->getMisses()); + if (isset($this->callSummaryData['misses'])) { + return (int) $this->callSummaryData['misses']; + } + + return (int)max(0, $this->finalProfile->getMisses() - $this->initialProfile->getMisses()); } /** @@ -75,6 +95,10 @@ class CacheProfileSummary */ public function getCalls() { + if (isset($this->callSummaryData['calls'])) { + return (int) $this->callSummaryData['calls']; + } + return $this->getHits() + $this->getMisses(); } @@ -86,7 +110,7 @@ class CacheProfileSummary $calls = $this->getCalls(); if ($calls == 0) { - return (float) 0; + return (float)0; } return $this->getHits() / $calls; @@ -100,7 +124,7 @@ class CacheProfileSummary $calls = $this->getCalls(); if ($calls == 0) { - return (float) 0; + return (float)0; } return $this->getMisses() / $calls; diff --git a/lib/Alchemy/Phrasea/Core/Profiler/TraceableCache.php b/lib/Alchemy/Phrasea/Core/Profiler/TraceableCache.php index 3f336b8abf..cbdaf1b9c9 100644 --- a/lib/Alchemy/Phrasea/Core/Profiler/TraceableCache.php +++ b/lib/Alchemy/Phrasea/Core/Profiler/TraceableCache.php @@ -5,6 +5,7 @@ namespace Alchemy\Phrasea\Core\Profiler; use Alchemy\Phrasea\Cache\Cache as PhraseaCache; use Alchemy\Phrasea\Cache\Exception; use Doctrine\Common\Cache\Cache; +use Symfony\Component\Stopwatch\Stopwatch; class TraceableCache implements Cache, PhraseaCache { @@ -32,12 +33,15 @@ class TraceableCache implements Cache, PhraseaCache 'calls_by_key' => [], ]; + private $stopWatch; + /*s* * @param PhraseaCache $cache */ - public function __construct(PhraseaCache $cache) + public function __construct(PhraseaCache $cache, Stopwatch $stopwatch = null) { $this->cache = $cache; + $this->stopWatch = $stopwatch ?: new Stopwatch(); } private function collect($type, $id, $hit = true, $result = null) @@ -90,6 +94,14 @@ class TraceableCache implements Cache, PhraseaCache return $this->namespace; } + /** + * @return int + */ + public function getTotalTime() + { + return $this->stopWatch->getEvent('cache')->getDuration(); + } + /** * @return array */ @@ -116,7 +128,9 @@ class TraceableCache implements Cache, PhraseaCache public function fetch($id) { try { + $this->stopWatch->start('cache'); $value = $this->cache->fetch($id); + $this->stopWatch->stop('cache'); } catch (\Exception $ex) { $value = false; @@ -138,7 +152,11 @@ class TraceableCache implements Cache, PhraseaCache { $this->collect('contains', $id); - return $this->cache->contains($id); + $this->stopWatch->start('cache'); + $result = $this->cache->contains($id); + $this->stopWatch->stop('cache'); + + return $result; } /** @@ -158,7 +176,11 @@ class TraceableCache implements Cache, PhraseaCache { $this->collect('save', $id); - return $this->cache->save($id, $data, $lifeTime); + $this->stopWatch->start('cache'); + $result = $this->cache->save($id, $data, $lifeTime); + $this->stopWatch->stop('cache'); + + return $result; } /** @@ -173,7 +195,11 @@ class TraceableCache implements Cache, PhraseaCache { $this->collect('delete', $id); - return $this->cache->delete($id); + $this->stopWatch->start('cache'); + $result = $this->cache->delete($id); + $this->stopWatch->stop('cache'); + + return $result; } /** @@ -202,7 +228,11 @@ class TraceableCache implements Cache, PhraseaCache */ public function getStats() { - return $this->cache->getStats(); + $this->stopWatch->start('cache'); + $result = $this->cache->getStats(); + $this->stopWatch->stop('cache'); + + return $result; } /** @@ -222,7 +252,9 @@ class TraceableCache implements Cache, PhraseaCache public function flushAll() { $this->collect('flush-all', null); + $this->stopWatch->start('cache'); $this->cache->flushAll(); + $this->stopWatch->stop('cache'); } /** diff --git a/templates-profiler/cache.html.twig b/templates-profiler/cache.html.twig index 3bdce87625..45b2f7a264 100644 --- a/templates-profiler/cache.html.twig +++ b/templates-profiler/cache.html.twig @@ -13,7 +13,7 @@ {% endset %} {% set icon %} Cache - {{ '%0.2f'|format(collector.summary.hitRatio * 100) }} % cache hit ratio + {{ '%0.2f'|format(collector.summary.hitRatio * 100) }} % in {{ collector.totalTime }} ms {% endset %} {% include '@WebProfiler/Profiler/toolbar_item.html.twig' with { 'link': profiler_url } %} {% endblock %} @@ -21,6 +21,10 @@ {% block menu %} Cache + + {{ collector.summary.hits }} + {{ '%0.0f'|format(collector.totalTime) }} ms + {% endblock %}