/** * Метод регистрирует новый секундомер для идентификатора * * @return Secundomer зарегистрированный идентификатор */ private final function registerSecundomer($ident) { if (!array_key_exists($ident, $this->secundomers)) { $this->secundomers[$ident] = Secundomer::inst($this->profilerId . '::' . $ident); } return $this->secundomers[$ident]; }
/** * Основной метод получения экземпляра. * * @param type $silentOnDoubleTry - признак, стоит ли нам ругаться, если мы * обнаруживаем зацикливание при попытке получения экземпляра класса. * * Это нужно для классов, которые выполняют сложную логику в конструкторе, которая * может привести к повторному вызову ::inst() внутри этого конструктора. * * Классы, которые используют эту возможность: * @link DbChangeListener - менеджер прослушивания изменений в БД */ protected static function inst($silentOnDoubleTry = false) { $class = get_called_class(); if (array_key_exists($class, self::$_insts_)) { return self::$_insts_[$class]; } if (array_key_exists($class, self::$_instsrq_)) { if ($silentOnDoubleTry) { return null; } raise_error("Double try to get singleton of [{$class}]"); } self::$_instsrq_[$class] = true; //Создаём экземпляр $sec = Secundomer::startedInst("Creating singleton of {$class}"); self::$_insts_[$class] = new $class(); $sec->stop(); //Экземпляр успешно создан unset(self::$_instsrq_[$class]); //Теперь добавим в профайлер. Всё это нужно для защиты от зацикливания. PsProfiler::inst(__CLASS__)->add($class, $sec); //Добавим к глобальному секундомеру - текущий $SECUNDOMER = self::$_secundomer_ ? self::$_secundomer_ : (self::$_secundomer_ = Secundomer::inst()); $SECUNDOMER->addSecundomer($sec); //Отлогируем PsLogger::inst(__CLASS__)->info("+ {$class} ({$sec->getAverage()} / {$SECUNDOMER->getTotalTimeRounded()})"); return self::$_insts_[$class]; }
function doTest() { global $HOST; global $TOTAL; global $HREFS; global $REQUESTS_CNT; $RESULTS = array(); $j = 0; foreach ($HREFS as $href => $name) { ++$j; $href = ensure_starts_with($href, '/'); $path = "http://{$HOST}{$href}"; $sec = Secundomer::inst(); for ($index = 0; $index <= $REQUESTS_CNT; $index++) { if ($index == 0) { //Пропустим первый вызов, на случай кеширования file_get_contents($path); continue; } $sec->start(); file_get_contents($path); $sec->stop(); ++$TOTAL; } dolog(pad_zero_left($j, 2) . '/' . count($HREFS) . " [{$path}] - " . $sec->getAverage() . ' (' . $sec->getTotalTime() . '/' . $sec->getCount() . ')'); $RESULTS[$path] = str_replace('.', ',', round($sec->getAverage(), 2)); } asort($RESULTS, SORT_DESC); $RESULTS = array_reverse($RESULTS, true); return $RESULTS; }
public static function testProductivity($callback, $count = 1000) { PsDefines::assertProductionOff(__CLASS__); check_condition(is_callable($callback), 'Передан некорректный callback для тестирования'); $s = Secundomer::inst(); for ($index = 0; $index < $count; $index++) { $s->start(); call_user_func($callback); $s->stop(); } return $s; }
public function buildContent() { PsUtil::startUnlimitedMode(); $s = Secundomer::inst(); $data = array(); for ($num = 0; $num <= self::REQUESTS_COUNT; $num++) { $s->start(); file_get_contents($this->url); $s->stop(); $data[$num]['time'] = $s->getTime(); $data[$num]['total'] = $s->getTotalTime(); if ($num == 0) { //Запросим один раз, чтобы сработало кеширование, если оно включено $s->clear(); } } $params = array('url' => $this->url, 'data' => $data, 'average' => $s->getAverage()); echo $this->getFoldedEntity()->fetchTpl($params); }
/** * Парсит файл профайлинга и возвращает массив вида: * ident=>Secundomer * Идентификатор здесь, это идентификатор профилируемой сущности, например - текст запроса. */ private function parseProfiler(DirItem $file) { $result = array(); $lines = $file->getFileLines(false); if (empty($lines)) { return $result; //--- } foreach ($lines as $line) { $tokens = explode('|', $line); if (count($tokens) != 3) { continue; } $ident = trim($tokens[0]); $count = trim($tokens[1]); $time = trim($tokens[2]); if (!$ident || !is_numeric($count) || !is_numeric($time)) { continue; } if (!array_key_exists($ident, $result)) { $result[$ident] = Secundomer::inst(); } $result[$ident]->add($count, $time); } return $result; }
PsSecurity::set(new PsSecurityProviderCmd()); } else { /* * Автоматически подключаемся к БД */ PsConnectionPool::configure(PsConnectionParams::production()); } /* * Инициализируем окружение, если мы работаем под ним. * Подключаемое окружение может установить свой провайдер безопасности. * Важно! Вызов не перемещать в if, так как метод init должен быть вызван обязательно. */ PsEnvironment::init(); /* * Инициализируем подсистему безопасности */ PsSecurity::init(); //Зарегистрируем функцию, подключающую админские ресурсы function ps_admin_on($force = false) { if ($force || AuthManager::isAuthorizedAsAdmin()) { Autoload::inst()->registerAdminBaseDir(); } } //Ну и сразу попытаемся подключить админские ресурсы ps_admin_on(); //Подключаем файл глобальных настроек, если он существует и мы работаем в рамках проекта PsGlobals::init(); //Получим экземпляр профайлера, чтобы подписаться на PsShotdown, если профилирование включено PsProfiler::inst()->add('ScriptInit', Secundomer::inst()->add(1, microtime(true) - SCRIPT_EXECUTION_START));