From 5c9b5576e6ae5ec71d3fa2b6ef49bc39018d1df7 Mon Sep 17 00:00:00 2001 From: Vladimir Razuvaev Date: Fri, 3 Aug 2018 21:03:48 +0700 Subject: [PATCH] Perf: memoize collectSubfields --- src/Executor/Executor.php | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/src/Executor/Executor.php b/src/Executor/Executor.php index 97d3ae3..4460e20 100644 --- a/src/Executor/Executor.php +++ b/src/Executor/Executor.php @@ -273,6 +273,11 @@ class Executor */ private $promises; + /** + * @var \SplObjectStorage + */ + private $subFieldCache; + /** * Executor constructor. * @@ -285,6 +290,7 @@ class Executor } $this->exeContext = $context; + $this->subFieldCache = new \SplObjectStorage(); } /** @@ -1311,12 +1317,28 @@ class Executor &$result ) { - // Collect sub-fields to execute to complete this value. - $subFieldNodes = new \ArrayObject(); - $visitedFragmentNames = new \ArrayObject(); + $subFieldNodes = $this->collectSubFields($returnType, $fieldNodes); + return $this->executeFields($returnType, $result, $path, $subFieldNodes); + } - foreach ($fieldNodes as $fieldNode) { - if (isset($fieldNode->selectionSet)) { + /** + * @param ObjectType $returnType + * @param $fieldNodes + * @return \ArrayObject + */ + private function collectSubFields(ObjectType $returnType, $fieldNodes) + { + if (!isset($this->subFieldCache[$returnType])) { + $this->subFieldCache[$returnType] = new \SplObjectStorage(); + } + if (!isset($this->subFieldCache[$returnType][$fieldNodes])) { + // Collect sub-fields to execute to complete this value. + $subFieldNodes = new \ArrayObject(); + $visitedFragmentNames = new \ArrayObject(); + foreach ($fieldNodes as $fieldNode) { + if (!isset($fieldNode->selectionSet)) { + continue; + } $subFieldNodes = $this->collectFields( $returnType, $fieldNode->selectionSet, @@ -1324,9 +1346,9 @@ class Executor $visitedFragmentNames ); } + $this->subFieldCache[$returnType][$fieldNodes] = $subFieldNodes; } - - return $this->executeFields($returnType, $result, $path, $subFieldNodes); + return $this->subFieldCache[$returnType][$fieldNodes]; } /**