Skip to content

Instantly share code, notes, and snippets.

@snpy
Last active October 1, 2015 15:37
Show Gist options
  • Save snpy/2016612 to your computer and use it in GitHub Desktop.
Save snpy/2016612 to your computer and use it in GitHub Desktop.
Plain old class with multiple getters vs class with single magic method replacing multiple getters.
<?php
define('MAX', 100000);
header('Content-Type: text/plain');
$test = @$_GET['test'] ? : @$argv[1];
$test = $test . '.php';
if (false === file_exists($test)) {
$test = 'Test1.php';
}
$mem = memory_get_peak_usage();
require $test;
$mt = microtime(1);
for ($i = MAX; false === empty($i); --$i) {
$new = new Test();
$new->getTitle0();
unset($new);
}
echo 'time [s]: ', (microtime(1) - $mt), PHP_EOL, 'mem [B]: ', (memory_get_peak_usage() - $mem), PHP_EOL;
<?php
class Test
{
public $title0 = 'string value';
public $title1 = 'string value';
public $title2 = 'string value';
public $title3 = 'string value';
public $title4 = 'string value';
public $title5 = 'string value';
public $title6 = 'string value';
public $title7 = 'string value';
public $title8 = 'string value';
public $title9 = 'string value';
public function getTitle0()
{
return $this->title0;
}
public function getTitle1()
{
return $this->title1;
}
public function getTitle2()
{
return $this->title2;
}
public function getTitle3()
{
return $this->title3;
}
public function getTitle4()
{
return $this->title4;
}
public function getTitle5()
{
return $this->title5;
}
public function getTitle6()
{
return $this->title6;
}
public function getTitle7()
{
return $this->title7;
}
public function getTitle8()
{
return $this->title8;
}
public function getTitle9()
{
return $this->title9;
}
}
<?php
class Test
{
public $title0 = 'string value';
public $title1 = 'string value';
public $title2 = 'string value';
public $title3 = 'string value';
public $title4 = 'string value';
public $title5 = 'string value';
public $title6 = 'string value';
public $title7 = 'string value';
public $title8 = 'string value';
public $title9 = 'string value';
public function __call($name, $args)
{
$field = 'title' . substr($name, -1);
return $this->$field;
}
}
<?php
class Test
{
public $title0 = 'string value';
public $title1 = 'string value';
public $title2 = 'string value';
public $title3 = 'string value';
public $title4 = 'string value';
public $title5 = 'string value';
public $title6 = 'string value';
public $title7 = 'string value';
public $title8 = 'string value';
public $title9 = 'string value';
public function getTitle0()
{
$this->somethingHeavy();
return $this->title0;
}
public function getTitle1()
{
$this->somethingHeavy();
return $this->title1;
}
public function getTitle2()
{
$this->somethingHeavy();
return $this->title2;
}
public function getTitle3()
{
$this->somethingHeavy();
return $this->title3;
}
public function getTitle4()
{
$this->somethingHeavy();
return $this->title4;
}
public function getTitle5()
{
$this->somethingHeavy();
return $this->title5;
}
public function getTitle6()
{
$this->somethingHeavy();
return $this->title6;
}
public function getTitle7()
{
$this->somethingHeavy();
return $this->title7;
}
public function getTitle8()
{
$this->somethingHeavy();
return $this->title8;
}
public function getTitle9()
{
$this->somethingHeavy();
return $this->title9;
}
protected function somethingHeavy()
{
// Very simple SQL call.
usleep(5);
}
}
<?php
class Test
{
public $title0 = 'string value';
public $title1 = 'string value';
public $title2 = 'string value';
public $title3 = 'string value';
public $title4 = 'string value';
public $title5 = 'string value';
public $title6 = 'string value';
public $title7 = 'string value';
public $title8 = 'string value';
public $title9 = 'string value';
public function __call($name, $args)
{
$field = 'title' . substr($name, -1);
$this->somethingHeavy();
return $this->$field;
}
protected function somethingHeavy()
{
// Very simple SQL call.
usleep(5);
}
}
@snpy
Copy link
Author

snpy commented Mar 11, 2012

Intentionally everything is super simple. Note benchmark is not using call_user_func nor call_user_func_array.

Running: php run_test.php Test1
Gave results like:

time [s]: 0.602390050888
mem [B]: 11432

Running: php run_test.php Test2
Gave results like:

time [s]: 1.60734391212
mem [B]: 80

As I see it: magic create as overheat (it's obvious it can't be quicker), but if we want to replace multiple simple methods (those where call_user_func would not be required) then we should not hesitate.

Exemplary results were run on machine:

CPU: 2.16 GHz C2D
Mem: 4 GB 667 MHz DDR2

PHP 5.3.10 with Suhosin-Patch (cli) (built: Mar  5 2012 15:05:07) 
Copyright (c) 1997-2012 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2012 Zend Technologies
    with Xdebug v2.1.2, Copyright (c) 2002-2011, by Derick Rethans

@snpy
Copy link
Author

snpy commented Mar 11, 2012

I decided to add 2 more test to show that __magic overheat is not as bad as it looks.
Above you see ~265% difference comparing Test2-time to Test1-time.

But comparing Test4-time to Test3-time we're getting ~133% calculated from results below (note: you should perform those test by yourself to see difference as I took one of the highest numbers for Test4 and one of the lowest numbers for Test3 just to stretch difference a bit more.

Running: php run_test.php Test3
Gave results like:

time [s]: 2.58065390587
mem [B]: 19448

Running: php run_test.php Test4
Gave results like:

time [s]: 3.42838096619
mem [B]: 3312

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment