Created
April 2, 2012 22:32
-
-
Save tyler-sommer/2287660 to your computer and use it in GitHub Desktop.
__call versus reflection
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 | |
/** | |
* A Simple Operation Benchmark Class | |
* | |
* @author Tyler Sommer | |
*/ | |
class Benchmark { | |
protected $_length; | |
protected $_tests = array(); | |
protected $_results = array(); | |
/** | |
* @param int $length The number of iterations per test | |
*/ | |
public function __construct($length = 1000) { | |
$this->_length = $length; | |
} | |
/** | |
* Register a test | |
* | |
* @param string $name (Friendly) Name of the test | |
* @param callback $callback A valid callback | |
*/ | |
public function register($name, $callback) { | |
$this->_tests[$name] = $callback; | |
} | |
/** | |
* Execute the registered tests and display the results | |
*/ | |
public function execute() { | |
$adjustment = round($this->_length * .1, 0); | |
echo "Running " . count($this->_tests) . " tests, {$this->_length} times each...\nThe {$adjustment} highest and lowest results will be disregarded.\n\n"; | |
foreach ($this->_tests as $name => $test) { | |
$results = array(); | |
for ($x = 0; $x < $this->_length; $x++) { | |
ob_start(); | |
$start = time() + microtime(); | |
call_user_func($test); | |
$results[] = round((time() + microtime()) - $start, 10); | |
ob_end_clean(); | |
} | |
sort($results); | |
// remove the lowest and highest 10% (leaving 80% of results) | |
for ($x = 0; $x < $adjustment; $x++) { | |
array_shift($results); | |
array_pop($results); | |
} | |
$avg = array_sum($results) / count($results); | |
echo "For {$name}, out of " . count($results) . " runs, average time was: " . sprintf("%.10f", $avg) . " secs.\n"; | |
$this->_results[$name] = $avg; | |
} | |
asort($this->_results); | |
reset($this->_results); | |
$fastestResult = each($this->_results); | |
reset($this->_results); | |
echo "\n\nResults:\n"; | |
printf("%-25s\t%-20s\t%s\n", "Test Name", "Time", "+ Interval"); | |
foreach ($this->_results as $name => $result) { | |
$interval = $result - $fastestResult["value"]; | |
printf("%-25s\t%-20s\t%s\n", $name, sprintf("%.10f", $result), "+" . sprintf("%.10f", $interval)); | |
} | |
} | |
} | |
class TestClass | |
{ | |
protected function myMethod() | |
{ | |
return true; | |
} | |
public function __call($method, $args) | |
{ | |
return call_user_func_array(array($this, $method), $args); | |
} | |
public function myPublicMethod() | |
{ | |
return true; | |
} | |
} | |
$bm = new Benchmark(25000); | |
$bm->register("reflection", function() { | |
$obj = new TestClass(); | |
$reflected = new ReflectionClass('TestClass'); | |
$method = $reflected->getMethod('myMethod'); | |
$method->setAccessible(true); | |
$result = $method->invoke($obj); | |
}); | |
$bm->register("__call", function() { | |
$obj = new TestClass(); | |
$result = $obj->myMethod(); | |
}); | |
$bm->register("public", function() { | |
$obj = new TestClass(); | |
$result = $obj->myPublicMethod(); | |
}); | |
$bm->execute(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment