Skip to content

Commit

Permalink
Merge pull request #8193 from kkmuffme/improve-psalm-performance
Browse files Browse the repository at this point in the history
Various minor improvements to speed up by ~10%
  • Loading branch information
orklah committed Jun 28, 2022
2 parents d6624c5 + 9058608 commit 4bc803d
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 10 deletions.
3 changes: 2 additions & 1 deletion src/Psalm/Internal/Algebra.php
Expand Up @@ -136,14 +136,15 @@ public static function simplifyCNF(array $clauses): array
if (!$clause_a->reconcilable || $clause_a->wedge) {
continue;
}
$clause_a_keys = array_keys($clause_a->possibilities);

if (count($clause_a->possibilities) !== 1 || count(array_values($clause_a->possibilities)[0]) !== 1) {
foreach ($cloned_clauses as $clause_b) {
if ($clause_a === $clause_b || !$clause_b->reconcilable || $clause_b->wedge) {
continue;
}

if (array_keys($clause_a->possibilities) === array_keys($clause_b->possibilities)) {
if ($clause_a_keys === array_keys($clause_b->possibilities)) {
$opposing_keys = [];

foreach ($clause_a->possibilities as $key => $a_possibilities) {
Expand Down
20 changes: 16 additions & 4 deletions src/Psalm/Internal/Clause.php
Expand Up @@ -10,15 +10,17 @@
use function array_unique;
use function array_values;
use function count;
use function hash;
use function implode;
use function ksort;
use function md5;
use function reset;
use function serialize;
use function sort;
use function strpos;
use function substr;

use const PHP_VERSION_ID;

/**
* @internal
*
Expand Down Expand Up @@ -106,11 +108,15 @@ public function __construct(
} else {
ksort($possibilities);

foreach ($possibilities as $i => $_) {
foreach ($possibilities as $i => $v) {
if (count($v) < 2) {
continue;
}
sort($possibilities[$i]);
}

$this->hash = md5(serialize($possibilities));
$data = serialize($possibilities);
$this->hash = PHP_VERSION_ID >= 80100 ? hash('xxh128', $data) : hash('md4', $data);
}
}

Expand All @@ -120,8 +126,14 @@ public function contains(Clause $other_clause): bool
return false;
}

foreach ($other_clause->possibilities as $var => $_) {
if (!isset($this->possibilities[$var])) {
return false;
}
}

foreach ($other_clause->possibilities as $var => $possible_types) {
if (!isset($this->possibilities[$var]) || count(array_diff($possible_types, $this->possibilities[$var]))) {
if (count(array_diff($possible_types, $this->possibilities[$var]))) {
return false;
}
}
Expand Down
13 changes: 10 additions & 3 deletions src/Psalm/Internal/Provider/ClassLikeStorageCacheProvider.php
Expand Up @@ -17,6 +17,7 @@
use function igbinary_serialize;
use function igbinary_unserialize;
use function is_dir;
use function is_null;
use function mkdir;
use function serialize;
use function strtolower;
Expand Down Expand Up @@ -75,9 +76,15 @@ public function writeToCache(ClassLikeStorage $storage, string $file_path, strin
{
$fq_classlike_name_lc = strtolower($storage->name);

$cache_location = $this->getCacheLocationForClass($fq_classlike_name_lc, $file_path, true);
$storage->hash = $this->getCacheHash($file_path, $file_contents);

// check if we have it in cache already
$cached_value = $this->loadFromCache($fq_classlike_name_lc, $file_path);
if (!is_null($cached_value) && $cached_value->hash === $storage->hash) {
return;
}

$cache_location = $this->getCacheLocationForClass($fq_classlike_name_lc, $file_path, true);
if ($this->config->use_igbinary) {
file_put_contents($cache_location, igbinary_serialize($storage));
} else {
Expand Down Expand Up @@ -110,9 +117,9 @@ public function getLatestFromCache(
return $cached_value;
}

private function getCacheHash(?string $file_path, ?string $file_contents): string
private function getCacheHash(?string $_unused_file_path, ?string $file_contents): string
{
$data = ($file_path ? $file_contents : '') . $this->modified_timestamps;
$data = $file_contents ? $file_contents : $this->modified_timestamps;
return PHP_VERSION_ID >= 80100 ? hash('xxh128', $data) : hash('md4', $data);
}

Expand Down
7 changes: 5 additions & 2 deletions src/Psalm/Internal/Provider/FileStorageCacheProvider.php
Expand Up @@ -117,9 +117,12 @@ public function removeCacheForFile(string $file_path): void
}
}

private function getCacheHash(string $file_path, string $file_contents): string
private function getCacheHash(string $_unused_file_path, string $file_contents): string
{
$data = ($file_path ? $file_contents : '') . $this->modified_timestamps;
// do not concatenate, as $file_contents can be big and performance will be bad
// the timestamp is only needed if we don't have file contents
// as same contents should give same results, independent of when file was modified
$data = $file_contents ? $file_contents : $this->modified_timestamps;
return PHP_VERSION_ID >= 80100 ? hash('xxh128', $data) : hash('md4', $data);
}

Expand Down

0 comments on commit 4bc803d

Please sign in to comment.