Перегрузка методов и свойств в PHP

мая 17, 2007 by admin

Задача: Проверить насколько перегруженные методы и свойства медленнее явных.

Публичные методы

Набросаем небольшой класс:

class Classic {  public $fooProp;  public $barProp;

  public function getFooProp() {      return $this->fooProp;  }

  public function setFooProp($foo) {      $this->fooProp = $foo;  }

  public function getBarProp() {      return $this->barProp;  }

  public function setBarProp($bar) {      $this->barProp = $bar;  }}

Проведем тест на скорость выполнения публичных методов. Исходя из

$iterations = 10000;echo ‘<p>Доступ через прописанные сеттеры/геттеры  - ‘;$time_start = microtime(1);for ($i=0; $i < $iterations; $i++) {  $obj = new Classic();  $obj->setFooProp($i);  $tmp = $obj->getBarProp();  $tmp = $obj->getFooProp();  $tmp = $obj->getBarProp();  $tmp = $obj->getFooProp();  $tmp = $obj->getBarProp();  $tmp = $obj->getFooProp();  $tmp = $obj->getBarProp();  $tmp = $obj->getFooProp();  $tmp = $obj->getBarProp();}$times = round($iterations / (microtime(1) - $time_start));echo $times . ‘ в секунду</p>’;

Результаты тестов на 10000 итераций:

Доступ через прописанные сеттеры/геттеры - 136552 в секунду

Перегрузка обращений к свойствам объекта (__set, __get)

Класс Overloaded реализует функционал класса Classic, с помощью перегрузки методов(__call) и доступа к свойствам(__set, __get):

<?phpclass Overloaded {  protected $fields = array(  ‘fooProp’ => false,  ‘barProp’ => false  );

  protected function _generateNoPropertyException($prop) {      throw new Exception(’Undefined property ‘ . $prop);  }

  public function __get($name) {      if(isset($this->fields[$name])) {          return $this->fields[$name];      } else {          $this->_generateNoPropertyException($name);      }  }

  public function __set($name,$value) {      if (isset($this->fields[$name])) {          $this->fields[$name] = $value;      } else {          $this->_generateNoPropertyException($name);      }  }

  public function getBarProp() {      return $this->fields[’barProp’];  }

  protected function __call($mthd, $args = array()) {      $type = substr($mthd, 0, 3);      if(’get’ == $type) {          return $this->__set(strtolower(substr($mthd, 3, 1)).substr($mthd, 4),$args);      } elseif(’set’ == $type) {          return $this->__get(strtolower(substr($mthd, 3, 1)).substr($mthd, 4));      }      throw new Exception(”No such method ‘$mthd’ in ” . get_class($this));  }}

Протестируем:

echo '<p>Доступ через перегруженные сеттеры/геттеры  - ';$time_start = microtime(1);for ($i=0; $i < $iterations; $i++) {  $obj = new Overloaded();  $obj->fooProp = $i;  $tmp = $obj->barProp;  $tmp = $obj->fooProp;  $tmp = $obj->barProp;  $tmp = $obj->fooProp;  $tmp = $obj->barProp;  $tmp = $obj->fooProp;  $tmp = $obj->barProp;  $tmp = $obj->fooProp;  $tmp = $obj->barProp;}$times = round($iterations / (microtime(1) - $time_start));echo $times . ‘ в секунду</p>’;

Получаем результат:

Доступ через перегруженные сеттеры/геттеры - 56004 в секунду

Перегрузка методов (__call)

Тестировать будем на нашем классе Overloaded:
echo ‘<p>Доступ через эмулированные сеттеры/геттеры - ‘;
$time_start = microtime(1);
for ($i=0; $i < $iterations; $i++) {
$obj = new Overloaded();
$obj->setFooProp($i);
$tmp = $obj->getBarProp();
$tmp = $obj->getFooProp();
$tmp = $obj->getBarProp();
$tmp = $obj->getFooProp();
$tmp = $obj->getBarProp();
$tmp = $obj->getFooProp();
$tmp = $obj->getBarProp();
$tmp = $obj->getFooProp();
$tmp = $obj->getBarProp();
}
$times = round($iterations / (microtime(1) - $time_start));
echo $times . ‘ в секунду</p>’;

highlight_file(__FILE__);

Результат:

Доступ через эмулированные сеттеры/геттеры - 27468 в секунду

Выводы

Вот результаты всех трех тестов:

Доступ через прописанные сеттеры/геттеры - 136552 в секундуДоступ через перегруженные сеттеры/геттеры - 56004 в секундуДоступ через эмулированные сеттеры/геттеры - 27468 в секунду

На диаграмме это выглядит следующим образом:

Сравнительно большая разница. Но если учесть, что сервер на котором проводилось тестирование достаточно сильно загружен, и тем не менее способен ежесекундно обрабатывать примерно 27,5 тысяч объектов, то отказ от использования overload это экономия на спичках в чистом виде.

Исходники полного теста: setget.php (3,2 Кб)

Posted in Без рубрики |

Leave a Comment

Please note: Comment moderation is enabled and may delay your comment. There is no need to resubmit your comment.