Skip to content

Commit f041da5

Browse files
committed
Memoize CallableType::describe() per verbosity level
ObjectType::isSuperTypeOf() keys its cache by describe(VerbosityLevel::cache()) of the other type, so a union of classes with a callable(...) describes the same CallableType once per class member. Since describe() prints through TypeNodeDescriber (a PHPDoc node traversal swapping name nodes, then the printer), that became the bulk of the time for such unions: a file with 1,000 calls of a function taking T|A1|...|A10|callable(A1, A2, A3, A4): T described 140,000 callables, 7,000 of them distinct. The description is now cached per level, as ClosureType, UnionType and IntersectionType already do. The turbo extension mirrors the cache. Amp-Thread-ID: https://ampcode.com/threads/T-01a1b250-3c08-762d-acb0-9cdf8e7a210e
1 parent 4890a6f commit f041da5

4 files changed

Lines changed: 1049 additions & 6 deletions

File tree

‎src/Type/CallableType.php‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@ class CallableType implements CompoundType, CallableParametersAcceptor
7979

8080
private Assertions $assertions;
8181

82+
/** @var array<int, string> */
83+
private array $cachedDescriptions = [];
84+
8285
/**
8386
* @api
8487
* @param list<ParameterReflection>|null $parameters
@@ -335,7 +338,7 @@ public function equals(Type $type): bool
335338

336339
public function describe(VerbosityLevel $level): string
337340
{
338-
return $level->handle(
341+
return $this->cachedDescriptions[$level->getLevelValue()] ??= $level->handle(
339342
static fn (): string => 'callable',
340343
function (): string {
341344
$assertedParameterNames = [];

0 commit comments

Comments
 (0)