Created
December 12, 2020 14:38
-
-
Save klkvsk/98eb1c3b1cc35b77ebd86bdc1b8820a3 to your computer and use it in GitHub Desktop.
php-enum property collection benchmarks
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
require __DIR__ . '/../vendor/autoload.php'; | |
$classes = require __DIR__ . '/classes.php'; | |
return function (callable $propertyReader) use ($classes) { | |
$t1 = microtime(true); | |
$numFiles = 0; | |
$numProps = 0; | |
foreach ($classes as $className) | |
{ | |
$numFiles++; | |
$fields = $propertyReader($className); | |
$numProps += count($fields); | |
} | |
$t2 = microtime(true); | |
echo "Read $numFiles files, $numProps properties total\n"; | |
echo "Total time consumed: "; | |
echo number_format(1000 * ($t2 - $t1), 2, '.', ' ') . " ms\n"; | |
}; | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
$numFiles = 1000; | |
$numFieldGroups = 2; | |
$numFieldsInGroup = 5; | |
function cleanup($dir) { | |
/** @var SplFileInfo[] $files */ | |
$files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS)); | |
foreach ($files as $file) { | |
unlink($file->getPathname()); | |
} | |
} | |
$generatedDir = __DIR__ . '/generated'; | |
if (is_dir($generatedDir)) { | |
cleanup($generatedDir); | |
} else { | |
mkdir($generatedDir); | |
} | |
$classes = []; | |
for ($i = 0; $i < $numFiles; $i++) { | |
$className = 'GeneratedEnum' . $i; | |
$classCode = "<?php" . PHP_EOL . PHP_EOL; | |
$classCode .= 'use PaLabs\Enum\Enum;' . PHP_EOL . PHP_EOL . PHP_EOL; | |
$classCode .= "class $className extends Enum" . PHP_EOL; | |
$classCode .= "{" . PHP_EOL; | |
for ($g = 0; $g < $numFieldGroups; $g++) { | |
$classCode .= " public static $className"; | |
for ($f = 0; $f < $numFieldsInGroup; $f++) { | |
$classCode .= sprintf(" \$VALUE_%02X_%02X", $g, $f); | |
$classCode .= ($f+1 == $numFieldsInGroup) ? ';' : ','; | |
} | |
$classCode .= PHP_EOL; | |
} | |
$classCode .= "}" . PHP_EOL; | |
$filename = "$generatedDir/$className.php"; | |
file_put_contents($filename, $classCode); | |
$classes[$filename] = $className; | |
} | |
$autoload = '<?php' . PHP_EOL; | |
foreach ($classes as $filename => $className) { | |
$autoload .= "require '$filename';" . PHP_EOL; | |
} | |
$autoload .= PHP_EOL; | |
$autoload .= 'return [' . PHP_EOL; | |
foreach ($classes as $filename => $className) { | |
$autoload .= ' "' . $filename . '" => ' . $className . '::class,' . PHP_EOL; | |
} | |
$autoload .= '];' . PHP_EOL; | |
file_put_contents(__DIR__ . '/classes.php', $autoload); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
$bench = require 'bench.php'; | |
$bench(function ($className) | |
{ | |
$class = new ReflectionClass($className); | |
$shortClass = $class->getShortName(); | |
$fileContent = file_get_contents($class->getFileName()); | |
// use regexp to extract public static properties with type of enum class name | |
// [\s]+? - any space (including \n symbol), ? - lazy qualifier | |
$pattern = "/public[\s]+?static[\s]+?".$shortClass."[\s]+?([^;]+?);/i"; | |
preg_match_all($pattern, $fileContent, $matches); | |
if(count($matches) < 2) { | |
return []; | |
} | |
$allFields = []; | |
foreach($matches[1] as $fieldsStr) { | |
$fields = explode(',', $fieldsStr); | |
$fields = array_map('trim', $fields); | |
$fields = array_map( | |
fn(string $fieldName) => substr($fieldName, 1), | |
$fields | |
); | |
$allFields = array_merge($allFields, $fields); | |
} | |
return $allFields; | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
$bench = require 'bench.php'; | |
$bench(function ($className) | |
{ | |
$enumValues = []; | |
$classHierarchy = []; | |
$class = new ReflectionClass($className); | |
$properties = $class->getProperties(\ReflectionProperty::IS_STATIC | \ReflectionProperty::IS_PUBLIC); | |
foreach ($properties as $property) { | |
$type = $property->getType(); | |
if (!$type instanceof \ReflectionNamedType) { | |
continue; | |
} | |
$matched = false; | |
if ($type->getName() === $class->getName()) { | |
$matched = true; | |
} else if ($type->getName() === 'self' || $type->getName() == 'parent') { | |
$matched = true; | |
} else if (class_exists($type->getName()) && is_subclass_of($class->getName(), $type->getName())) { | |
$matched = true; | |
} | |
if ($matched) { | |
$declClassName = $property->getDeclaringClass()->getName(); | |
if (!isset($enumValues[$declClassName])) { | |
$enumValues[$declClassName] = []; | |
$classHierarchy[] = $declClassName; | |
} | |
$enumValues[$declClassName][] = $property->getName(); | |
} | |
} | |
$list = []; | |
foreach (array_reverse($classHierarchy) as $declClassName) { | |
foreach ($enumValues[$declClassName] as $value) { | |
$list[] = [ $declClassName, $value ]; | |
} | |
} | |
return $list; | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
## 1000 files, 10 values in each | |
-- file parsing reader -- | |
Read 1000 files, 10000 properties total | |
Total time consumed: 102.24 ms | |
-- reflection reader -- | |
Read 1000 files, 10000 properties total | |
Total time consumed: 45.46 ms | |
## 1000 files, 100 values in each | |
-- file parsing reader -- | |
Read 1000 files, 100000 properties total | |
Total time consumed: 319.40 ms | |
-- reflection reader -- | |
Read 1000 files, 100000 properties total | |
Total time consumed: 397.64 ms |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
mkdir generated | |
echo "generating enums" | |
php create-enums.php | |
echo "" | |
echo "-- file parsing reader --" | |
php read-with-file-parsing.php | |
echo "" | |
echo "-- reflection reader --" | |
php read-with-reflection-only.php |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment