Created
November 6, 2013 11:34
-
-
Save bwaidelich/7334680 to your computer and use it in GitHub Desktop.
A simple script to compare performance of magic __call methods to real implementations
This file contains hidden or 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 | |
class MagicMethodFixture { | |
/** | |
* @var array | |
*/ | |
protected $configurations; | |
public function __construct() { | |
$this->configurations = array( | |
'foo' => 'bar', | |
'Bar' => 'baz' | |
); | |
} | |
/** | |
* @param string $configurationKey | |
* @return mixed | |
*/ | |
public function get($configurationKey) { | |
return $this->configurations[$configurationKey]; | |
} | |
/** | |
* @param string $methodName | |
* @param array $arguments | |
* @return mixed | |
*/ | |
public function __call($methodName, array $arguments) { | |
if (substr($methodName, 0, 3) === 'get') { | |
$configurationKey = lcfirst(substr($methodName, 3)); | |
return $this->configurations[$configurationKey]; | |
} elseif (substr($methodName, 0, 3) === 'has') { | |
$configurationKey = lcfirst(substr($methodName, 3)); | |
return isset($this->configurations[$configurationKey]); | |
} | |
trigger_error('Call to undefined method ' . get_class($this) . '::' . $methodName, E_USER_ERROR); | |
} | |
} | |
$iterations = 1000000; | |
$fixture = new MagicMethodFixture(); | |
echo '<h2>magic __call:</h2>'; | |
$start = microtime(TRUE); | |
for ($i = 0; $i < $iterations; $i ++) { | |
$fixture->getFoo(); | |
} | |
$end = microtime(TRUE); | |
echo '<p>' . ($end - $start) . ' seconds</p>'; | |
echo '<h2>real implementation:</h2>'; | |
$start = microtime(TRUE); | |
for ($i = 0; $i < $iterations; $i ++) { | |
$fixture->get('foo'); | |
} | |
$end = microtime(TRUE); | |
echo '<p>' . ($end - $start) . ' seconds</p>'; |
This test didn't mean to be fair. I just wanted to find out how much slower a magic getSomething()
is compared to a get('something')
implementation.
I created a version that doesn't do string manipulations or use call_user_func
inside of __call
to make this more fair:
https://gist.github.com/kemo/b180bba7eec7626e02e7755ac5bb96f1
Still, __call
is ~5 times slower even on PHP 8
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The magic and the "not magic" method are not comparable:
Of course you will get more time spent in the "magic" version. A fair test would involve doing thing a lot different.