пятница, 27 июня 2008 г.

Zend Framework тест производительности

Zend Framework радует своей гибкостью и большим количеством нодулей, но какой ценой...
Возьмем пример * @author Александр Махомет aka San для http://zendframework.ru

в начале index.php вставим:



class microTimer {
function start() {
global $starttime;
$mtime = microtime ();
$mtime = explode (' ', $mtime);
$mtime = $mtime[1] + $mtime[0];
$starttime = $mtime;
}
function stop() {
global $starttime;
$mtime = microtime ();
$mtime = explode (' ', $mtime);
$mtime = $mtime[1] + $mtime[0];
$endtime = $mtime;
$totaltime = round (($endtime - $starttime), 5);
return $totaltime;
}
}


и сделаем замер времени выполнения:



require 'Zend/Loader.php';

/**
* Kernel
*
* Главный системный класс
*
* @param array $config Массив конфигурации
* @author Александр Махомет aka San для http://zendframework.ru
*/
class Kernel {

/**
* Запуск приложения
*
*/
public static function run($config) {

try {
echo "
".microTimer::stop()." Запуск autoload";
// Запуск autoload
Zend_Loader::registerAutoload();
echo "
".microTimer::stop()." Запуск autoload";
// Создание объекта конфигурации
$cnf = new Zend_Config($config);
echo "
".microTimer::stop()." Создание объекта конфигурации";
// Занесение объекта конфигурации в реестр
Zend_Registry::set('cnf', $cnf);
echo "
".microTimer::stop()." Занесение объекта конфигурации в реестр";
// Подключение к базе данных
self::setDbAdapter();
echo "
".microTimer::stop()." Подключение к базе данных";
// Подключение файла с правилами маршрутизации
if (file_exists($cnf->path->system.'routes.php')) {
require($cnf->path->system.'routes.php');
}
echo "
".microTimer::stop()." Подключение файла с правилами маршрутизации";
// Инициализация Zend_Layout, настройка пути к макетам, а также имени главного макета.
Zend_Layout::startMvc(array(
'layoutPath' => $cnf->path->layouts,
'layout' => 'index',
));
echo "
".microTimer::stop()." Инициализация Zend_Layout, настройка пути к макетам, а также имени главного макета.";
// Получение объекта Zend_Layout
$layout = Zend_Layout::getMvcInstance();
echo "
".microTimer::stop()." Получение объекта Zend_Layout";
// Инициализация объекта Zend_View
$view = $layout->getView();
echo "
".microTimer::stop()." Инициализация объекта Zend_View";
// Настройка расширения макетов
$layout->setViewSuffix('tpl');
echo "
".microTimer::stop()." Настройка расширения макетов";
// Задание базового URL
$view->baseUrl = $cnf->url->base;
echo "
".microTimer::stop()." Задание базового URL";
// Задание пути для view части
$view->setBasePath($cnf->path->views);
echo "
".microTimer::stop()." Задание пути для view части";
// Установка объекта Zend_View
$layout->setView($view);
echo "
".microTimer::stop()." Установка объекта Zend_View";
// Настройка расширения view скриптов с помощью Action помошников
$viewRenderer = new Zend_Controller_Action_Helper_ViewRenderer();
$viewRenderer->setView($view)
->setViewSuffix('tpl');

Zend_Controller_Action_HelperBroker::addHelper($viewRenderer);
echo "
".microTimer::stop()." Настройка расширения view скриптов с помощью Action помошников";
// Создание объекта front контроллера
$front = Zend_Controller_Front::getInstance();
echo "
".microTimer::stop()." Создание объекта front контроллера ";
// Настройка front контроллера, указание базового URL, правил маршрутизации
$front->setBaseUrl($cnf->url->base)
->throwexceptions(true)
->setRouter($router);
echo "
".microTimer::stop()." Настройка front контроллера, указание базового URL, правил маршрутизации ";
// Запуск приложения, в качестве параметра передаем путь к папке с контроллерами
Zend_Controller_Front::run($cnf->path->controllers);
echo "
".microTimer::stop()." Запуск приложения, в качестве параметра передаем путь к папке с контроллерами";
}
catch (Exception $e) {
// Перехват исключений
Error::catchException($e);
}
}

/**
* Установка соединения с базой данных и помещение его объекта в реестр.
*/
public static function setDbAdapter() {

// Получение объекта конфигурации из реестра
$cnf = Zend_Registry::get('cnf');

// Подключение к БД, так как Zend_Db "понимает" Zend_Config, нам достаточно передать специально сформированный объект конфигурации в метод factory
$db = Zend_Db::factory($cnf->db);

// Задание адаптера по умолчанию для наследников класса Zend_Db_Table_Abstract
Zend_Db_Table_Abstract::setDefaultAdapter($db);

// Занесение объекта соединения c БД в реестр
Zend_Registry::set('db', $db);


}

}



В итоге не очень хороший результат:

0.0001 Запуск autoload
0.00992 Создание объекта конфигурации
0.01626 Занесение объекта конфигурации в реестр
0.17438 Подключение к базе данных
0.09229 Подключение файла с правилами маршрутизации
0.34841 Инициализация Zend_Layout, настройка пути к макетам, а также имени главного макета.
4.0E-5 Получение объекта Zend_Layout
0.07809 Инициализация объекта Zend_View
4.0E-5 Настройка расширения макетов
5.0E-5 Задание базового URL
0.00013 Задание пути для view части
3.0E-5 Установка объекта Zend_View
6.0E-5 Настройка расширения view скриптов с помощью Action помошников
3.0E-5 Создание объекта front контроллера
6.0E-5 Настройка front контроллера, указание базового URL, правил маршрутизации
0.85284 Запуск приложения, в качестве параметра передаем путь к папке с контроллерами

в сумме получается:
0.04383 Запуск autoload
0.05778 Создание объекта конфигурации
0.07456 Занесение объекта конфигурации в реестр
0.25064 Подключение к базе данных
0.34036 Подключение файла с правилами маршрутизации
0.68982 Инициализация Zend_Layout, настройка пути к макетам, а также имени главного макета.
0.68989 Получение объекта Zend_Layout
0.76389 Инициализация объекта Zend_View
0.76396 Настройка расширения макетов
0.76402 Задание базового URL
0.76415 Задание пути для view части
0.76418 Установка объекта Zend_View
0.76425 Настройка расширения view скриптов с помощью Action помошников
0.76428 Создание объекта front контроллера
0.76434 Настройка front контроллера, указание базового URL, правил маршрутизации
1.60107 Запуск приложения, в качестве параметра передаем путь к папке с контроллерами

1.6 секунды критичное значение для скрипта

среда, 25 июня 2008 г.

Решение трудностей MySQL 5 вызов процедур в PHP

Убил три дня на изучение простой вещи, надеюсь кому то поможет.

Использование Функций и Процедур в СУБД MySQL 5.0-5.1

Функция не может звозвращать значение типа TABLE или ROW и даже CURSOR, только вещественные значения такие как INT, FLOAT, CHAR и т.д. Поэтому функции лучше использовать как вспомогательные элементы к процедурам ИМХО.
"RETURN в процедуре" как оказалось существует два варианта:
Первый возвращение через параметры OUT и IN/OUT Выглядит это так:
CALL prname('INPARAM1', @a1) SELECT @a1;
На лицо недостатки метода нужно заранее знать количество необходимых параметров, что лично для меня не подходило

Второй вариант:
Вывод через процедуры такого вида:

DELIMITER $$

CREATE DEFINER=`root`@`localhost` PROCEDURE `msgbox`(IN xid INT(11), IN xlang char(2))
BEGIN
select id, text, lang from messages where id=xid and lang=xlang limit 0, 1;
END$$

DELIMITER ;

То что надо можем вставлять любе запросы любые разветвления, алгоритмы и т.д.
Но, есть одно НО =)
А именно в моем SQLyog все работает на ура, но когда выполняю примерно так на PHP (apache/OS Win) $result = mysql_query($query, $this->db_id) ;

Возвращается ошибка

MySQL Error!
------------------------

The Error returned was:
PROCEDURE real.sel_komnat can't return a result set in the given context

Error Number:
1312

На официальном форуме, ни слова про это нет. На русском вообще тем по пальцам пересчитать можно, у буржуев советы только по выводу через параметры как в первом способе.


На самом деле все гораздо проще... Стоило только подключить библиотеку MySQLi как все заработало на ура. fetch Проходит без проблем.

Пост первый

теперь я блоггер