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 */
private $exeContext;
/** @var \SplObjectStorage */
private $subFieldCache;
private function __construct(ExecutionContext $context)
{
if (! self::$UNDEFINED) {
@ -66,6 +69,7 @@ class Executor
}
$this->exeContext = $context;
$this->subFieldCache = new \SplObjectStorage();
}
/**
@ -1260,26 +1264,42 @@ class Executor
$path,
&$result
) {
// 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,
$subFieldNodes,
$visitedFragmentNames
);
}
$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.
$subFieldNodes = new \ArrayObject();
$visitedFragmentNames = new \ArrayObject();
foreach ($fieldNodes as $fieldNode) {
if (!isset($fieldNode->selectionSet)) {
continue;
}
$subFieldNodes = $this->collectFields(
$returnType,
$fieldNode->selectionSet,
$subFieldNodes,
$visitedFragmentNames
);
}
$this->subFieldCache[$returnType][$fieldNodes] = $subFieldNodes;
}
return $this->subFieldCache[$returnType][$fieldNodes];
}
/**
* Implements the "Evaluating selection sets" section of the spec
* for "read" mode.