Improve performance of DefaultPolicy (#10585)

Add memoization to selectPreferredPackages
main
Yanick Witschi 2 years ago committed by GitHub
parent 3a1e07f3cc
commit f125fc1d0a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -27,6 +27,10 @@ class DefaultPolicy implements PolicyInterface
private $preferStable; private $preferStable;
/** @var bool */ /** @var bool */
private $preferLowest; private $preferLowest;
/** @var array<int, array<string, array<int, int>>> */
private $preferredPackageResultCachePerPool;
/** @var array<int, array<string, int>> */
private $sortingCachePerPool;
/** /**
* @param bool $preferStable * @param bool $preferStable
@ -63,11 +67,25 @@ class DefaultPolicy implements PolicyInterface
*/ */
public function selectPreferredPackages(Pool $pool, array $literals, string $requiredPackage = null): array public function selectPreferredPackages(Pool $pool, array $literals, string $requiredPackage = null): array
{ {
sort($literals);
$resultCacheKey = implode(',', $literals).$requiredPackage;
$poolId = spl_object_id($pool);
if (isset($this->preferredPackageResultCachePerPool[$poolId][$resultCacheKey])) {
return $this->preferredPackageResultCachePerPool[$poolId][$resultCacheKey];
}
$packages = $this->groupLiteralsByName($pool, $literals); $packages = $this->groupLiteralsByName($pool, $literals);
foreach ($packages as &$nameLiterals) { foreach ($packages as &$nameLiterals) {
usort($nameLiterals, function ($a, $b) use ($pool, $requiredPackage): int { usort($nameLiterals, function ($a, $b) use ($pool, $requiredPackage, $poolId): int {
return $this->compareByPriority($pool, $pool->literalToPackage($a), $pool->literalToPackage($b), $requiredPackage, true); $cacheKey = 'i'.$a.'.'.$b.$requiredPackage; // i prefix -> ignoreReplace = true
if (isset($this->sortingCachePerPool[$poolId][$cacheKey])) {
return $this->sortingCachePerPool[$poolId][$cacheKey];
}
return $this->sortingCachePerPool[$poolId][$cacheKey] = $this->compareByPriority($pool, $pool->literalToPackage($a), $pool->literalToPackage($b), $requiredPackage, true);
}); });
} }
@ -79,11 +97,17 @@ class DefaultPolicy implements PolicyInterface
$selected = \call_user_func_array('array_merge', array_values($packages)); $selected = \call_user_func_array('array_merge', array_values($packages));
// now sort the result across all packages to respect replaces across packages // now sort the result across all packages to respect replaces across packages
usort($selected, function ($a, $b) use ($pool, $requiredPackage): int { usort($selected, function ($a, $b) use ($pool, $requiredPackage, $poolId): int {
return $this->compareByPriority($pool, $pool->literalToPackage($a), $pool->literalToPackage($b), $requiredPackage); $cacheKey = $a.'.'.$b.$requiredPackage; // no i prefix -> ignoreReplace = false
if (isset($this->sortingCachePerPool[$poolId][$cacheKey])) {
return $this->sortingCachePerPool[$poolId][$cacheKey];
}
return $this->sortingCachePerPool[$poolId][$cacheKey] = $this->compareByPriority($pool, $pool->literalToPackage($a), $pool->literalToPackage($b), $requiredPackage);
}); });
return $selected; return $this->preferredPackageResultCachePerPool[$poolId][$resultCacheKey] = $selected;
} }
/** /**

Loading…
Cancel
Save