Perf: memoize collectSubfields

This commit is contained in:
Vladimir Razuvaev 2018-07-30 00:36:10 +07:00
parent bedbd32fb7
commit 2f2b54a3d6

View File

@ -59,6 +59,9 @@ class Executor
/** @var ExecutionContext */ /** @var ExecutionContext */
private $exeContext; private $exeContext;
/** @var \SplObjectStorage */
private $subFieldCache;
private function __construct(ExecutionContext $context) private function __construct(ExecutionContext $context)
{ {
if (! self::$UNDEFINED) { if (! self::$UNDEFINED) {
@ -66,6 +69,7 @@ class Executor
} }
$this->exeContext = $context; $this->exeContext = $context;
$this->subFieldCache = new \SplObjectStorage();
} }
/** /**
@ -1260,12 +1264,27 @@ class Executor
$path, $path,
&$result &$result
) { ) {
$subFieldNodes = $this->collectSubFields($returnType, $fieldNodes);
return $this->executeFields($returnType, $result, $path, $subFieldNodes);
}
/**
* @param ObjectType $returnType
* @param $fieldNodes
* @return ArrayObject
*/
private function collectSubFields(ObjectType $returnType, $fieldNodes): ArrayObject
{
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. // Collect sub-fields to execute to complete this value.
$subFieldNodes = new \ArrayObject(); $subFieldNodes = new \ArrayObject();
$visitedFragmentNames = new \ArrayObject(); $visitedFragmentNames = new \ArrayObject();
foreach ($fieldNodes as $fieldNode) { foreach ($fieldNodes as $fieldNode) {
if (! isset($fieldNode->selectionSet)) { if (!isset($fieldNode->selectionSet)) {
continue; continue;
} }
@ -1276,8 +1295,9 @@ class Executor
$visitedFragmentNames $visitedFragmentNames
); );
} }
$this->subFieldCache[$returnType][$fieldNodes] = $subFieldNodes;
return $this->executeFields($returnType, $result, $path, $subFieldNodes); }
return $this->subFieldCache[$returnType][$fieldNodes];
} }
/** /**