- PVSM.RU - https://www.pvsm.ru -
Автор не будет пытаться научить читательа всяческим штучкам. Равно как и показать что-то новое, старое и убедить кого-то что-то использовать. Поводом для написания послужили вынужденные оптимизации скорости работы медленного кода. Оказалось, что медленно он работает именно из-за «Магических» методов в моем контексте. Поискав, автор не нашел четкой информации, как медленно работают магические методы — все, что нашел автор просто «медленнее», поэтому пришлось получать результаты самостоятельно. Так посмотрим же на все это с точки зрения сухой статистики!
В свое время узнав о «Магических» методах php отсюда [1] а также из ряда других источников, автору это все понравилось, ибо нет ничего лучше, чем интеллектуальный код, который в сочитании с кешем умеет сам понимать, находить, подтягивать и отдавать то, чего от него просят.
Вооружившись примером магии [2], автор принялся эксперементировать, да так, что ему это понравилось. Как всегда, простые примеры работают быстро, в пылу страсти азарта автор и не заметил как начал использовать заклинания методы __call, __set и __get чуть ли не в каждом создаваемом классе.
Но вот стала незадача. Казалось бы код, который логически ненагружен, стал выполняться долго не так быстро как хотелось бы. Автора загрызла жаба совесть и началось.
Автор не желает перегружать читателя массами кода и всякой всячиной, поэтому в свободное время написал мини-кусочки специально для наглядности.
Вот они два простейших класса, не претендующих на оригинальность:
class A{
public $a;
public function foo($arg) {
return $arg;
}
}
class B{
public $params;
public function __call($fName, $args) {
return $args[0];
}
public function __set($name, $value) {
$params[$name] = $value;
}
}
В этих самых классах методы специально сделаны очень простыми — они только возвращают то, что принимают.
Вот и тесты кусочки кода, которые вызывают методы по 1000000 10^6 раз:
$a = new A();
for ($i = 0; $i < 1000000; $i++) {
$a->foo($i);
}
$b = new B();
for ($i = 0; $i < 1000000; $i++) {
$b->foo($i);
}

Это занимало (в секундах) ~0.20 для A против ~0.63 для B
Заметим, что дополнительные проверки не вводились специально для минимизации погрешностей.
$a = new A();
for ($i = 0; $i < 1000000; $i++) {
$a->a = 1;
}
$b = new B();
for ($i = 0; $i < 1000000; $i++) {
$b->b = 1;
}

Т.е. просто совместим первый и второй тесты
class A{
public $a;
public function foo($arg) {
$this->a = $arg;
return $arg;
}
}
class B{
public $params;
public function __call($fName, $args) {
$this->b = $args[0];
return $args[0];
}
public function __set($name, $value) {
$params[$name] = $value;
}
}
И выполним тесты из первого примера — вызов метода.

Автор, порефакторив код, написав нужные методы, все-же оставил в ряде мест эту магию, но впредь будет вести себя значительно осторожнее с заклинаниями такими методами, т.к. известно, что Любая палка о двух концах. Спасибо за внимание!
Автор: aimodify
Источник [3]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/programmirovanie/36245
Ссылки в тексте:
[1] отсюда: http://php.net/manual/ru/language.oop5.magic.php
[2] магии: http://www.php.net/manual/ru/language.oop5.overloading.php#example-210
[3] Источник: http://habrahabr.ru/post/182836/
Нажмите здесь для печати.