В процессе рефакторинга одного проекта, первую итерацию мы написали с душой. ООП, неймспесы, геттеры/сеттеры, и так далее.
В общем, как можно догадаться, оно не взлетело, и вот почему.
На многие вещи в PHP при применении ООП происходит страшный overhead. Вдруг оказывается, что правильные геттеры/сеттеры настолько жрут ресурсы, что неправильные паблик свойства гораздо быстрее, чем можно себе только представить. И еще куча проблем.
Простому тесту и посвящена эта статья, а выводы делать вам самим.
Возьмем простой тестик.
<?php
$profilerEnabled = false;
if ( isset($_GET['debug']) ) {
ini_set('display_errors', true);
error_reporting(E_ALL);
$_SERVER['PROJECT_MODE_DEVELOP'] = 1;
$_SERVER['adminallow'] = 1;
}
if ( isset($_GET['profile']) ) {
if ( extension_loaded('xhprof') ) {
xhprof_enable(XHPROF_FLAGS_CPU + XHPROF_FLAGS_MEMORY);
$profilerEnabled = true;
}
}
//define('APP_ROOT', dirname(dirname(dirname(__FILE__))));
//
//include_once('LSF/Autoload.php');
//
//$app = LSF_App::instance();
//$app->initialize();
//
//LSF2_App_Config::setFromFile(null, APP_ROOT . '/misc/config.ini');
class PrivateTest {
private $_1;
private $_2;
private $_3;
private $_4;
private $_5;
public function __construct($one, $two, $three, $four, $five) {
$this->_1 = $one;
$this->_2 = $two;
$this->_3 = $three;
$this->_4 = $four;
$this->_5 = $five;
}
public function get1() {
return $this->_1;
}
public function get2() {
return $this->_2;
}
public function get3() {
return $this->_3;
}
public function get4() {
return $this->_4;
}
public function get5() {
return $this->_5;
}
}
class PublicTest {
public $_1;
public $_2;
public $_3;
public $_4;
public $_5;
public function __construct($one, $two, $three, $four, $five) {
$this->_1 = $one;
$this->_2 = $two;
$this->_3 = $three;
$this->_4 = $four;
$this->_5 = $five;
}
}
$a = 0;
for($i = 1; $i <= 100000; $i++) {
$object = new PrivateTest(1, 2, 3, 4, 5);
$a += privateGetterTest($object);
}
$b = 0;
for($i = 1; $i <= 100000; $i++) {
$object = new PublicTest(1, 2, 3, 4, 5);
$b += publicGetterTest($object);
}
if ( $profilerEnabled ) {
$data = serialize(xhprof_disable());
$uniq = uniqid();
$dir = ini_get('xhprof.output_dir');
if ( !$dir ) {
trigger_error('Unable to save profiler data, please, specify the xhprof.output_dir directive in php.ini', E_USER_WARNING);
} else {
if ( !is_dir($dir) ) {
mkdir($dir, 0777, true);
}
$file = fopen($dir.'/'.$uniq.'.xhprof', "w+");
if ( $file ) {
fwrite($file, $data);
fclose($file);
echo "<br><br><b><a href='http://lst222.b.ls1.ru/xhprof/?run={$uniq}' target='_blank'>xhprof</a></b>";
} else {
trigger_error('Unable to save profiler data. Could not open file.', E_USER_WARNING);
}
}
}
function privateGetterTest($object) {
$d = $object->get1() +
$object->get2() +
$object->get3() +
$object->get4() +
$object->get5();
return $d;
}
function publicGetterTest($object) {
$d = $object->_1 +
$object->_2 +
$object->_3 +
$object->_4 +
$object->_5;
return $d;
}
?>
И вот что получим на выходе
Результаты говорят сами за себя — если хотите крутое ООП + highload, либо пишите просто и местами «неправильно», либо мощные куски переносите на более производительные технологии. Мы решили переносом части логики на уровень хранимок в БД PostgreSQL (9ка), оно масштабируется на ура.
Автор: Cord