Skip to content

Instantly share code, notes, and snippets.

@prolic
Created July 11, 2012 11:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save prolic/3089749 to your computer and use it in GitHub Desktop.
Save prolic/3089749 to your computer and use it in GitHub Desktop.
performance test on different isSubclassOf implementations
<?php
// our test cases
interface A {}
class B implements A {}
class C extends B {}
// test implementations (suggestion from ralph schindler, cache can be put in protected static class member)
function isSubclassOf1($className, $type)
{
$className = ltrim($className, '\\');
$type = ltrim($type, '\\');
static $isSubclassFuncCache = null; // null as unset, array when set
if ($isSubclassFuncCache === null) {
$isSubclassFuncCache = array();
}
$caseInsensitiveParent = strtolower($className);
if (!array_key_exists($caseInsensitiveParent, $isSubclassFuncCache)) {
$parents = class_parents($className, true) + class_implements($className, true);
$isSubclassFuncCache[$caseInsensitiveParent] = array_change_key_case($parents, CASE_LOWER);
}
return (isset($isSubclassFuncCache[$caseInsensitiveParent][strtolower($type)]));
}
// reflection implementation, uses no cache at all
function isSubclassOf2($className, $type)
{
if (is_subclass_of($className, $type)) {
return true;
}
if (!interface_exists($type)) {
return false;
}
$r = new ReflectionClass($className);
return $r->implementsInterface($type);
}
// reflection implementation, using cache, too
function isSubclassOf3($className, $type)
{
if (is_subclass_of($className, $type)) {
return true;
}
if (!interface_exists($type)) {
return false;
}
static $isSubclassFuncCache = null; // null as unset, array when set
if ($isSubclassFuncCache === null) {
$isSubclassFuncCache = array();
}
$caseInsensitiveParent = strtolower($className);
$caseInsensitiveChild = strtolower($type);
if (!array_key_exists($caseInsensitiveParent, $isSubclassFuncCache)) {
$r = new ReflectionClass($className);
if ($r->implementsInterface($type)) {
$isSubclassFuncCache[$caseInsensitiveParent][$caseInsensitiveChild] = true;
}
}
return (isset($isSubclassFuncCache[$caseInsensitiveParent][$caseInsensitiveChild]));
}
$s = microtime(1);
for ($i = 0; $i < 500000; $i++ ) {
isSubclassOf1('B', 'A');
isSubclassOf1('C', 'A');
}
var_dump(isSubclassOf1('b', 'A'));
var_dump(isSubclassOf1('c', 'a'));
echo microtime(1) - $s . PHP_EOL;
$s = microtime(1);
for ($i = 0; $i < 500000; $i++ ) {
isSubclassOf2('b', 'A');
isSubclassOf2('c', 'A');
}
var_dump(isSubclassOf2('b', 'A'));
var_dump(isSubclassOf2('c', 'a'));
echo microtime(1) - $s . PHP_EOL;
$s = microtime(1);
for ($i = 0; $i < 500000; $i++ ) {
isSubclassOf3('B', 'A');
isSubclassOf3('C', 'A');
}
var_dump(isSubclassOf3('b', 'A'));
var_dump(isSubclassOf3('c', 'a'));
echo microtime(1) - $s . PHP_EOL;
// test 1: PHP 5.4.0
// output:
bool(true)
bool(true)
1.8527138233185
bool(true)
bool(true)
0.5012640953064
bool(true)
bool(true)
0.50209498405457
// test 2: PHP 5.3.6 FPM
// output:
bool(true)
bool(true)
2.8868138790131
bool(true)
bool(true)
1.7050089836121
bool(true)
bool(true)
1.8733060359955
// notice that the reflection implementation is even faster without cache !
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment